60 votes

Est-ce que sizeof (enum) == sizeof (int) est toujours?

Est la sizeof(enum) == sizeof(int), toujours ?

  • Ou est-il dépendant du compilateur?
  • Est-il faux de dire, comme compilateur sont optimisés pour des longueurs de mots (alignement de la mémoire) ie o int est le mot-taille sur un compilateur? Signifie, qu'il n'existe pas de traitement de pénalité si je utiliser les énumérations, comme ce serait le mot aligné?
  • N'est-il pas mieux si j'ai mis tous les codes de retour dans un enum, comme je l'ai clairement ne vous inquiétez pas sur les valeurs à obtenir, seuls les noms tout en vérifiant les types de retour. Si c'est le cas habitude #DEFINE être mieux que cela permettrait d'économiser de la mémoire.

Quelle est la pratique habituelle? Si j'ai le transport de ces types de retour sur un réseau et le traitement doit être fait à l'autre extrémité, que préférez-vous les énumérations/#définit/ const ints.

EDIT - il suffit de vérifier sur le net, comme le compilateur ne pas symboliquement lien macros, comment les gens debug puis, comparer la valeur de l'entier avec le fichier d'en-tête?

À partir des Réponses données -je suis en ajoutant cette ligne ci-dessous, que j'ai besoin de plus de précisions-

"Donc, c'est la mise en œuvre définis, et sizeof(enum) peut être égal à sizeof(char), c'est à dire 1."

  • N'est-il pas dire que le compilateur vérifie la plage de valeurs dans les énumérations, puis affecter la mémoire. Je ne le pense pas, bien sûr, je ne sais pas. Quelqu'un peut-il svp m'expliquer ce qui est "peut-être".

36voto

Johannes Schaub - litb Points 256113

Il est dépendant du compilateur et de peuvent différer entre les énumérations. Voici la sémantique

enum X { A, B };

// A has type int
assert(sizeof(A) == sizeof(int));

// some integer type. Maybe even int. This is
// implementation defined. 
assert(sizeof(enum X) == sizeof(some_integer_type));

Notez que "certains type integer" en C99 peut également inclure l'étendue types d'entiers (dont la mise en œuvre, cependant, a du document, si on leur donne). Le type de l'énumération est un type qui permet de stocker la valeur d'un agent recenseur (A et B dans ce cas).

Je ne pense pas que les sanctions à l'utilisation d'énumérations. Les agents recenseurs sont partie intégrante des expressions constantes trop (de sorte que vous pouvez l'utiliser pour initialiser statique ou de la portée des variables, par exemple), et je les préfère à des macros à chaque fois que possible.

Les agents recenseurs n'ont pas besoin de la mémoire d'exécution. Seulement lorsque vous créez une variable de type énumération, vous pouvez utiliser de la mémoire d'exécution. Il suffit de penser agents recenseurs comme la compilation des constantes de temps.

Je voudrais juste utiliser un type qui permet de stocker l'agent recenseur valeurs (que je devrais connaître la rudesse de la gamme de valeurs de l'avant-main), en fonte, et de l'envoyer sur le réseau. De préférence, le type doit avoir une certaine largeur fixe, comme int32_t, de sorte qu'il ne vient pas à des conflits lors de différentes machines sont impliqués. Ou je voudrais imprimer le nombre, de numérisation et de l'autre côté, qui se débarrasse de certains de ces problèmes.


Réponse à Modifier

Ainsi, le compilateur n'est pas requis pour l'utilisation de n'importe quelle taille. Une chose facile à voir, c'est que le signe des valeurs de la matière - types non signés peuvent avoir gain de performances significatif dans certains calculs. Ce qui suit est le comportement de GCC 4.4.0 sur ma boîte

int main(void) {
  enum X { A = 0 };
  enum X a; // X compatible with "unsigned int"
  unsigned int *p = &a;
}

Mais si vous affectez un -1, puis GCC choisit d'utiliser int comme le type qui X est compatible avec

int main(void) {
  enum X { A = -1 };
  enum X a; // X compatible with "int"
  int *p = &a;
}

À l'aide de l'option --short-enums de la GCC, qui permet d'utiliser le plus petit type de raccord de toutes les valeurs.

int main() {
  enum X { A = 0 };
  enum X a; // X compatible with "unsigned char"
  unsigned char *p = &a;
}

18voto

Martin v. Löwis Points 61768

C99, 6.7.2.2p4 dit

Chaque type énuméré est compatible avec char, signé de type entier, ou un unsigned type entier. Le choix du type la mise en œuvre est définie,108), mais doit être capable de représenter les les valeurs de tous les membres de la l'énumération. [...]

Note de bas de page 108 ajoute

Une mise en œuvre peut retarder le choix de l'entier type jusqu'à ce que l'énumération de tous les constantes ont été vus.

C'est donc la mise en œuvre définis, et sizeof(enum) peut être égal à sizeof(char), c'est à dire 1.

En choisissant la taille d'une petite plage d'entiers, il y a toujours une pénalité. Si vous faites petit dans la mémoire, il y a probablement un traitement de peine; si vous faites des en grand, il est un espace de pénalité. C'est un espace-temps compromis.

Les codes d'erreur sont généralement #définit, parce qu'ils ont besoin pour être extensible: les différentes bibliothèques peuvent ajouter de nouveaux codes d'erreur. Vous ne pouvez pas le faire avec des enums.

13voto

IRBMe Points 2127

Est la sizeof(enum) == sizeof(int), toujours

Le C ANSI standard dit:

Chaque type énuméré doit être compatible avec le char, un entier signé un type ou d'un type entier non signé. Le choix du type de mise en œuvre est définie. (6.7.2.2 Enumerationspecifiers)

Donc, je prendrais cela pour dire non.

Si c'est le cas habitude #DEFINE être mieux que cela permettrait d'économiser de la mémoire.

De quelle façon l'aide d'définit économiser de la mémoire sur l'aide d'un enum? Un enum est juste un type qui permet de fournir plus d'informations pour le compilateur. Dans l'exécutable, c'est juste transformé en un entier, tout comme le préprocesseur convertit une macro créée avec des #define pour sa valeur.

Qu'est-ce que l'habitude de pratiquer. Je si j'ai le transport de ces types de retour sur un réseau et le traitement doit être fait à l'autre extrémité

Si vous prévoyez de valeurs de transport sur un réseau et de les traiter sur l'autre extrémité, vous devez définir un protocole. Décider de la taille en bits de chaque type, l'endianess (l'ordre dans lequel les octets sont) et assurez-vous de respecter pour que le client et le serveur de code. Aussi, ne pas simplement supposer que parce qu'il se produit au travail, vous avez vu juste. Il pourrait être que l'endianess, par exemple, votre client et le serveur plates-formes de correspondances, mais ce n'est pas toujours le cas.

5voto

INS Points 5679

Non.

Exemple: le compilateur CodeSourcery

Lorsque vous définissez une énumération comme celle-ci:

 enum MyEnum1 {
A=1,
B=2,
C=3
};
// will have the sizeof 1 (fits in a char)

enum MyEnum1 {
A=1,
B=2,
C=3,
D=400
};
// will have the sizeof 2 (doesn't fit in a char)
 

Détails de leur liste de diffusion

2voto

nuriaion Points 1678

Sur certains compilateurs, la taille d’une énumération dépend du nombre d’entrées dans l’énumération. (moins de 255 Entrys => Byte, Plus de 255 Entrys int) Mais cela dépend du compilateur et des paramètres du compilateur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X