Spécification de la taille du type enum en C
déjà lu dans cette question connexe , mais cherchait quelque chose d'un peu plus spécifique.
- Est-il un moyen de dire à votre compilateur précisément comment vous voulez que votre enum?
- Si oui, comment faites-vous? Je sais comment le spécifier en C#; est-il de même fait en C?
- Serait-il la peine? Lorsque la valeur d'enum est transmis à une fonction, il est passé comme une
int
- peu importe la valeur?
6 réponses
est-il possible de dire à votre compilateur précisément comment vous voulez que votre enum?
dans l'affaire no 151920920. Non conforme à la norme C.
Serait-il la peine?
cela dépend du contexte. Si vous parlez de passer des paramètres à des fonctions, alors non, cela ne vaut pas la peine de le faire (voir ci-dessous). S'il s'agit de sauvegarder de la mémoire lors de la construction d'agrégats du genre enum, ça vaut peut-être le coup. Cependant, dans C vous pouvez simplement utiliser un type entier de taille appropriée au lieu du type enum dans les agrégats. En C (par opposition à C++), les types enum et les types entiers sont presque toujours interchangeables.
lorsque la valeur enum est transmise à une fonction, sera-t-elle transmise en tant que valeur de taille int indépendamment?
beaucoup (la plupart) compilateurs de nos jours passer tous les paramètres comme des valeurs de mot naturel la taille de la plate-forme matérielle donnée. Par exemple, sur une plate-forme 64 bits, de nombreux compilateurs passeront tous les paramètres en tant que valeurs 64 bits, quelle que soit leur taille réelle, même si le type int
contient 32 bits sur cette plate-forme (donc, il n'est généralement pas passé en tant que valeur "int-sized" sur une telle plate-forme). Pour cette raison, il n'est pas logique d'essayer d'optimiser les tailles d'enum pour les besoins du passage des paramètres.
je crois qu'il y a un drapeau si vous utilisez GCC.
-fshort-enums
, Vous pouvez le forcer à faire au moins une certaine taille en définissant une valeur appropriée. Par exemple, si vous voulez que votre enum soit stocké dans la même taille qu'un int
, même si toutes les valeurs s'inscrivent dans un char
, vous pouvez faire quelque chose comme ceci:
typedef enum {
firstValue = 1,
secondValue = 2,
Internal_ForceMyEnumIntSize = MAX_INT
} MyEnum;
notez cependant que le comportement peut dépendre de l'implémentation.
comme vous le constatez, en passant une telle valeur à une fonction, elle sera étendue à une int de toute façon, mais si vous utilisez votre type dans un tableau ou une structure, alors la taille importera. Si vous vous souciez vraiment de la taille des éléments, vous devriez vraiment utiliser des types comme int8_t
, int32_t
, etc.
il y a aussi une autre façon si l'enum fait partie d'une structure:
struct something {
:0;
enum whatever field:CHAR_BIT;
:0;
};
le :0; peut être omis si le champ enum est entouré de champs normaux. S'il y a un autre bitfield avant, le :0 forcera l'alignement des bytes vers le prochain byte pour le champ qui le suit.
cela dépend des valeurs attribuées aux énums.
Ex: Si la valeur supérieure à 2^32-1 est stockée, la taille attribuée à l'enum global passera à la taille suivante.
stocke la valeur 0xffffffffff à une variable enum, elle donnera un avertissement si essayé de compiler dans un environnement 32 bits (arrondir l'avertissement) Où comme dans une compilation 64 bits, il sera réussi et la taille attribuée sera de 8 octets.
une autre façon est de jeter l'énum à l'intérieur d'une union comme suit:
union char_size {
char a;
enum {
a = 1,
b = 2,
} val;
};
cela forcera le compilateur à intégrer l'enum dans un char.