J'ai commencé à écrire le firmware de mon produit et je suis une recrue ici. J'ai parcouru de nombreux articles sur la non-utilisation des variables ou fonctions globales. Existe-t-il une limite pour l'utilisation de variables globales dans un système 8 bits ou s'agit-il d'un «non-non» complet? Comment dois-je utiliser des variables globales dans mon système ou dois-je les éviter complètement?
Je voudrais prendre de précieux conseils de votre part à ce sujet pour rendre mon firmware plus compact.
static
portée du fichier @endolith n'est pas la même chose que "globale", voir ma réponse ci-dessous.Réponses:
Vous pouvez utiliser des variables globales avec succès, tant que vous gardez à l'esprit les directives de @ Phil. Cependant, voici quelques bonnes façons d'éviter leurs problèmes sans rendre le code compilé moins compact.
Utilisez des variables statiques locales pour un état persistant auquel vous ne souhaitez accéder qu'à l'intérieur d'une fonction.
Utilisez une structure pour garder les variables liées ensemble, pour préciser où elles doivent être utilisées et où elles ne le sont pas.
Utilisez des variables statiques globales pour rendre les variables visibles uniquement dans le fichier C actuel. Cela empêche un accès accidentel par le code dans d'autres fichiers en raison de conflits de noms.
Enfin, si vous modifiez une variable globale dans une routine d'interruption et la lisez ailleurs:
volatile
.OU
la source
volatile
variables est de permettre au code s'exécutant dans un contexte d'exécution de laisser le code dans un autre contexte d'exécution savoir que quelque chose s'est produit. Sur un système 8 bits, un tampon qui va contenir une puissance de deux octets ne dépassant pas 128 peut être géré avec un octet volatile indiquant le nombre total d'octets à vie mis dans le tampon (mod 256) et un autre indiquant le nombre de vie d'octets extraits, à condition qu'un seul contexte d'exécution place les données dans le tampon et qu'un seul en retire les données.Les raisons pour lesquelles vous ne voudriez pas utiliser des variables globales dans un système 8 bits sont les mêmes que vous ne voudriez pas les utiliser dans un autre système: elles rendent difficile le raisonnement sur le comportement du programme.
Seuls les mauvais programmeurs se bloquent sur des règles comme "n'utilisez pas de variables globales". Les bons programmeurs comprennent la raison derrière les règles, puis traitent les règles plus comme des directives.
Votre programme est-il facile à comprendre? Son comportement est-il prévisible? Est-il facile d'en modifier des parties sans casser d'autres parties? Si la réponse à chacune de ces questions est oui , alors vous êtes sur la bonne voie pour un bon programme.
la source
Vous ne devez pas complètement éviter d'utiliser des variables globales ("globals" pour faire court). Mais, vous devez les utiliser judicieusement. Les problèmes pratiques d'une utilisation excessive des globaux:
Il est recommandé d'ajouter un préfixe
g_
au nom des variables globales. Par exemple,g_iFlags
,. Lorsque vous voyez la variable avec le préfixe dans le code, vous reconnaissez immédiatement qu'il s'agit d'un global.la source
static
drapeau deviendrait-il visible pour lemain()
? Voulez-vous dire que la même fonction qui a lestatic
peut le renvoyer à lamain()
dernière?L'avantage des structures de données globales dans le travail intégré est qu'elles sont statiques. Si chaque variable dont vous avez besoin est globale, vous ne manquerez jamais accidentellement de mémoire lorsque des fonctions sont entrées et que de l'espace est prévu pour elles sur la pile. Mais alors, à ce moment-là, pourquoi avoir des fonctions? Pourquoi pas une grande fonction qui gère toute la logique et les processus - comme un programme BASIC sans GOSUB autorisé. Si vous prenez cette idée assez loin, vous aurez un programme de langage d'assemblage typique des années 1970. Efficace et impossible à entretenir et à dépanner.
Utilisez donc les globaux judicieusement, comme les variables d'état (par exemple, si chaque fonction a besoin de savoir si le système est dans un état d'interprétation ou d'exécution) et d'autres structures de données qui doivent être vues par de nombreuses fonctions et, comme le dit @PhilFrost, c'est le comportement de vos fonctions prévisibles? Est-il possible de remplir la pile avec une chaîne d'entrée qui ne se termine jamais? Ce sont des questions pour la conception d'algorithmes.
Notez que statique a une signification différente à l'intérieur et à l'extérieur d'une fonction. /programming/5868947/difference-between-static-variable-inside-and-outside-of-a-function
/programming/5033627/static-variable-inside-of-a-function-in-c
la source
Les variables globales ne doivent être utilisées que pour un état véritablement global. L'utilisation d'une variable globale pour représenter quelque chose comme par exemple la latitude de la limite nord de la carte ne fonctionnera que s'il ne peut jamais y avoir qu'une seule "limite nord de la carte". Si à l'avenir le code pourrait devoir fonctionner avec plusieurs cartes ayant des limites nord différentes, le code qui utilise une variable globale pour la limite nord devra probablement être retravaillé.
Dans les applications informatiques typiques, il n'y a souvent aucune raison particulière de supposer qu'il n'y aura jamais plus d'un élément. Dans les systèmes embarqués, cependant, ces hypothèses sont souvent beaucoup plus raisonnables. Bien qu'il soit possible qu'un programme informatique typique soit appelé à prendre en charge plusieurs utilisateurs simultanés, l'interface utilisateur d'un système embarqué typique sera conçue pour être utilisée par un seul utilisateur interagissant avec ses boutons et son écran. En tant que tel, il aura à tout moment un état d'interface utilisateur unique. Concevoir le système de manière à ce que plusieurs utilisateurs puissent interagir avec plusieurs claviers et écrans nécessiterait beaucoup plus de complexité et prendrait beaucoup plus de temps à mettre en œuvre que de le concevoir pour un seul utilisateur. Si le système n'est jamais appelé à prendre en charge plusieurs utilisateurs, tout effort supplémentaire investi pour faciliter une telle utilisation sera gaspillé. Sauf s'il est probable qu'une assistance multi-utilisateurs sera nécessaire, il serait probablement plus sage de risquer d'avoir à supprimer le code utilisé pour une interface mono-utilisateur dans le cas où une assistance multi-utilisateurs est nécessaire, que de passer plus de temps à ajouter plusieurs support utilisateur qui ne sera probablement jamais nécessaire.
Un facteur connexe avec les systèmes embarqués est que dans de nombreux cas (impliquant notamment des interfaces utilisateur), le seul moyen pratique de prendre en charge plusieurs éléments serait d'utiliser plusieurs threads. En l'absence d'un autre besoin de multi-threading, il est probablement préférable d'utiliser une conception simple à un seul thread que d'augmenter la complexité du système avec un multi-threading qui n'est probablement jamais vraiment nécessaire. Si ajouter plus d'un élément nécessiterait de toute façon une énorme refonte du système, cela n'aura pas d'importance si cela nécessite également de retravailler l'utilisation de certaines variables globales.
la source
Beaucoup de gens sont confus à ce sujet. La définition d'une variable globale est:
Ce n'est pas la même chose que les variables de portée de fichier , qui sont déclarées par le mot-clé
static
. Ce ne sont pas des variables globales, ce sont des variables privées locales.Devriez-vous utiliser des variables globales? Il y a quelques cas où ça va:
Dans tous les autres cas, vous n'utiliserez jamais de variables globales. Il n'y a jamais de raison de le faire. Utilisez plutôt des variables d'étendue de fichier , ce qui est parfaitement correct.
Vous devez vous efforcer d'écrire des modules de code indépendants et autonomes conçus pour effectuer une tâche spécifique. À l'intérieur de ces modules, les variables de portée de fichier interne doivent résider en tant que membres de données privées. Cette méthode de conception est connue sous le nom d’orientation objet et est largement reconnue comme une bonne conception.
la source
.data
segment.