2008-12-14 5 views
120

Je crée un ensemble de valeurs enum, mais j'ai besoin que chaque valeur enum soit large de 64 bits. Si je me souviens bien, une énumération a généralement la même taille qu'un int; mais je pensais avoir lu quelque part que (au moins dans GCC) le compilateur peut faire à l'énumération toute la largeur dont ils ont besoin pour conserver leurs valeurs. Alors, est-il possible d'avoir une énumération de 64 bits de large?Quelle est la taille d'une énumération en C?

+1

Donc, si je comprends bien, 2^32 enums ne vous suffisent pas? Ou est-ce un souci d'alignement, pourquoi avez-vous besoin de ceux d'être 64 au lieu de 32, je suis très curieux. – jokoon

+1

@jokoon: Honnêtement, je ne m'en souviens plus.Je pense que je voulais que les énumérations contiennent des valeurs supérieures à 2^32-1. – mipadi

+0

Une utilisation serait si vous avez besoin d'une union entre une énumération et un pointeur. – Demi

Répondre

82

Un enum est seulement garanti suffisamment grand pour contenir les valeurs int. Le compilateur est libre de choisir le type réel utilisé en fonction des constantes d'énumération définies afin qu'il puisse choisir un type plus petit s'il peut représenter les valeurs que vous définissez. Si vous avez besoin de constantes d'énumération qui ne rentrent pas dans un int, vous devrez utiliser des extensions spécifiques au compilateur pour le faire.

+9

Votre première phrase semble entrer en conflit avec votre dernier. La contrainte est-elle qu'un 'enum' devrait être plus grand qu'un' int' ou plus petit? Après la réponse de @MichaelStum, votre première phrase devrait être "Un' enum' est seulement garanti pour entrer dans une valeur 'int'." – HaskellElephant

+0

En tant que vilain hack sensible à l'implémentation sur deux plates-formes complémentaires (est-ce que tous les systèmes actuels?), Vous pouvez forcer une énumération à être aussi grande qu'un int en s'assurant qu'il contient des valeurs négatives. Ce n'est pas une technique recommandée. – persiflage

+3

Cette réponse semble suggérer qu'une énumération est aussi grande qu'un 'int'. [La réponse de Michael Stum] (https://stackoverflow.com/a/366033/971090), qui fait référence à C99, indique qu'une énumération peut être aussi petite qu'un 'char'. –

75

Extrait de la norme actuelle C (C99): http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf

6.7.2.2 Dénombrement spécificateurs
[...]

Contraintes L'expression qui définit la valeur d'une constante d'énumération sont un entier expression constante ayant une valeur représentable en tant que int.
[...]
Chaque type énuméré doit être compatible avec char, un type entier signé ou un type entier non signé . Le choix du type est défini par l'implémentation, mais doit être capable de représenter les valeurs de tous les membres de l'énumération.

Non que les compilateurs sont bons à la suite de la norme, mais essentiellement: Si votre ENUM détient toute autre chose qu'un int, vous êtes profond « comportement non pris en charge qui peuvent revenir vous mordre dans un an ou deux » territoire.

+2

ayant seulement cela, ce qui suit est valide je pense: enum {LAST = INT_MAX, LAST1, LAST2}; donc LAST2 n'est pas représentable dans int, mais il n'y avait pas d'expression le définissant. –

+4

Dans le PDF actuel, il définit ceci: "Les identifiants d'une liste d'énumérateurs sont déclarés comme des constantes de type int [...]". J'ai omis cela pour le rendre pas trop bavard. –

+2

Remarque "* un * type entier signé ou * un * type entier non signé". Pas nécessairement 'int'. 'short' et' long' sont aussi des types entiers, et quel que soit le choix de l'implémentation, toutes les valeurs doivent correspondre ("* doit * être capable de représenter les valeurs de tous les membres de l'énumération"). –

12

Alors que les réponses précédentes sont correctes, certains compilateurs ont des options pour casser la norme et utiliser le plus petit type qui contiendra toutes les valeurs.

Exemple avec GCC:

enum ord __attribute__ ((__packed__)) { 
    FIRST = 1, 
    SECOND, 
    THIRD, 
}; 
STATIC_ASSERT(sizeof(enum ord) == 1) 
+7

En fait, autant que je peux voir cela ne brise pas la norme. Comme expliqué dans la réponse de Michael Stum, la norme permet au compilateur de choisir le type réel des énumérations, à condition que toutes les valeurs correspondent. – sleske

+1

J'ai travaillé avec des compilateurs MacOS C++ qui exploitent la plage limitée de valeurs d'une énumération pour les stocker dans des types plus petits. Je ne me souviens pas si c'était Metrowerks Codewarrior ou XCode. Ceci est dans la norme C++. Vous ne pouvez pas supposer sizeof (MyEnum) == sizeof (int) en général. – persiflage

-3

Tenir compte:

enum value{a,b,c,d,e,f,g,h,i,j,l,m,n}; 
value s; 
cout << sizeof(s) << endl; 

Cela donnera la sortie comme 4. Donc, peu importe le nombre d'éléments d'un ENUM contient, sa taille est toujours fixe.

+4

La réponse de Michael Stum est correcte. Ceci est spécifique au compilateur. Vous pouvez l'essayer vous-même avec IAR EWARM. IAR EWARM montre 1 pour votre exemple. S'il y a jusqu'à 255 éléments, il montre encore 1. Après l'ajout de 256e élément, il va jusqu'à 2. – desowin

+5

La question ne concerne pas C++. – Michas

0

La taille de stockage n'est pas influencée par la quantité de valeurs dans l'énumération. La taille de stockage est définie par l'implémentation, mais c'est généralement le sizeof(int).

+2

Ce n'est pas le cas pour tous les compilateurs. Certains compilateurs choisissent de stocker dans un type plus petit qui correspondra aux valeurs de cette énumération particulière. Voir au dessus. – persiflage

-1

Nous n'avons aucun contrôle sur la taille d'une variable enum. Cela dépend totalement de l'implémentation, et le compilateur donne la possibilité de stocker un nom pour un entier en utilisant enum, donc enum suit la taille d'un entier.

0

En langage C, un enum est garanti de taille de int. Il y a une option de temps de compilation (-fshort-enums) pour le rendre aussi court (Ceci est principalement utile dans le cas où les valeurs ne sont pas plus de 64K). Il n'y a pas d'option de temps de compilation pour augmenter sa taille à 64 bits.