Quelle est la taille dune énumération en C?


Meilleure réponse

Une énigme très épineuse, quand on doit faire correspondre les décalages de structure à travers les limites de la machine ou les protocoles réseau . La spécification indique que la taille doit être le minimum requis pour représenter la plus grande valeur quelle peut prendre. Ainsi, une énumération détat typique dune machine à états, par exemple, peut ne nécessiter quun octet.

Il ny a AFAIK que trois façons de contrôler la taille:

certains compilateurs (mais pas tous) ont un commutateur de compilateur pour forcer la taille à sizeof (int) ou à 32 bits. La syntaxe du commutateur nest pas la même entre, disons, MSC et gccc / clang.

La deuxième façon, si vous devez remplir un champ de 16 bits, est de définir une valeur max factice qui nécessite cette taille.

Lautre façon consiste à utiliser des styles int réguliers dans les définitions de structure, mais alors on oublie la commodité du débogueur de lui faire afficher la valeur par nom dénumération, et dobtenir uniquement des entiers à la place.

Ensuite, il faudra probablement spécifier que la structure contenant lénumération est compressée, pas complétée.

Réponse

Si aucune partie dune variable x est const ou volatile, et x nest pas de type tableau, puis la déclaration…

x = x;

… à peu près ne fait rien. Il « est bien formé. En supposant que x a été initialisé au préalable, ¹ il est également bien défini. Laffectation nest pas t vraiment changer létat du programme, avec quelques exceptions potentielles (voir ci-dessous).

Ceci est vrai même si x a un struct type.

struct foo {

char buf[42];

int x;

};

struct foo x = { "Hello World", 18 };

x = x; // no big deal.

Alors, quelle est l «erreur»? Ce nest pas du code utile , mais il y a beaucoup de code qui correspond à cette description. Ce nest quune erreur si vous vouliez faire autre chose et que vous avez manqué.

[Addendum: Étant donné l’inutilité de cette tâche, les compilateurs sont enclins à en avertir, car il est plutôt probable que vous l’avez fait signifie autre chose.]

Pourquoi le peu sur const et volatile? La restriction sur const est simple: cela signifie « lecture seule » et vous ne pouvez donc « pas y écrire. Du moins, pas avec une simple affectation.

Celui concernant volatile est plus délicat. Ce mot-clé indique que la valeur qualifiée par celui-ci peut être modifiée de manière non visible par limplémentation, et que les écritures dessus peuvent avoir des effets secondaires. Sans creuser ici dans un trou, en pratique, les seules opérations raisonnablement bien définies que vous pouvez effectuer sur un objet volatil ressemblent à ceci:

volatile int v;

int i;

i = v; // reads from v once, places into i.

v = i; // writes to v once with the contents of i.

Vous pouvez faire un peu plus que cela correctement avec volatile, mais seulement légèrement. Cest un sujet pour un autre jour. Il y a une raison pour laquelle C ++ 20 a abandonné toutes les utilisations de volatile, à quelques exceptions près. Leurs changements semblent assez raisonnables.

Jai mentionné quelques exceptions possibles ci-dessus. Jonas Oberhauser ma rappelé que tout remplissage dans un struct nest pas nécessairement préservé par cette affectation.

De plus, il est théoriquement possible que la représentation sous-jacente des objets change en raison de laffectation, si la même valeur peut être représentée de plusieurs façons.

Espérons que votre programme soit insensible aux deux possibilités. Si jamais vous regardez la représentation sous-jacente de lobjet, vous pourriez voir des différences. Des fonctions telles que memcmp peuvent le remarquer, par exemple. De même si vous utilisez des punitions de type .

¹ Et si ce nétait pas le cas, bienvenue dans comportement non défini, car vous vous heurtez probablement à lun de ces éléments:

  • La valeur dun objet avec une durée de stockage automatique est utilisée tant quelle est indéterminée ( 6.2 .4 , 6.7.9 , 6.8 ).
  • Une lvalue désignant un objet de durée de stockage automatique qui aurait pu être déclaré avec la classe de stockage de registre est utilisée dans un contexte qui nécessite le valeur de lobjet désigné, mais lobjet nest pas initialisé. ( 6.3.2.1 ).

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *