2008-12-14 49 views
120

Estoy creando un conjunto de valores enum, pero necesito que cada valor enum tenga 64 bits de ancho. Si recuerdo correctamente, una enumeración es generalmente del mismo tamaño que una int; pero pensé que leí en alguna parte que (al menos en GCC) el compilador puede hacer que la enumeración tenga el ancho que necesitan para mantener sus valores. Entonces, ¿es posible tener una enumeración de 64 bits de ancho?¿Cuál es el tamaño de una enumeración en C?

+1

Así que si entiendo bien, 2^32 enumeraciones no son suficientes para usted? ¿O es una preocupación de alineación, por qué necesitas que sean 64 en lugar de 32? Tengo mucha curiosidad. – jokoon

+1

@jokoon: Honestamente ya no recuerdo.Creo que quería que las enumeraciones contuvieran valores mayores que 2^32-1. – mipadi

+0

Un uso sería si necesitara una unión entre una enumeración y un puntero. – Demi

Respuesta

82

Un enum solo tiene la garantía de ser lo suficientemente grande para contener los valores int. El compilador puede elegir libremente el tipo real utilizado en función de las constantes de enumeración definidas para que pueda elegir un tipo más pequeño si puede representar los valores que defina. Si necesita constantes de enumeración que no se ajustan a un int, necesitará usar extensiones específicas del compilador para hacerlo.

+9

Tu primera frase parece estar en conflicto con la tuya. ¿La restricción es que un 'enum' debe ser más grande que un' int' o más pequeño? Siguiendo la respuesta de @MichaelStum, su primera oración debe ser "An' enum' solo se garantiza que se ajuste a un valor 'int'". – HaskellElephant

+0

Como un truco sensible a la implementación fea en plataformas de complemento a dos (¿eso es todos los sistemas en estos días?), Puede forzar una enumeración que sea tan grande como un int asegurándose de que contenga valores negativos. Aunque no es una técnica recomendada. – persiflage

+3

Esta respuesta parece sugerir que una enumeración es tan grande como un 'int'. [La respuesta de Michael Stum] (https://stackoverflow.com/a/366033/971090), que hace referencia a C99, dice que una enumeración puede ser tan pequeña como un 'char'. –

75

Tomado de la corriente de C estándar (C99): http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf

6.7.2.2 especificadores de enumeración
[...]
Restricciones
la expresión que define el valor de una constante de enumeración será un entero expresión constante que tiene un valor representable como int.
[...]
Cada tipo enumerado debe ser compatible con caracteres, un tipo entero con signo o un tipo de entero sin signo . La elección del tipo está definida por la implementación, pero debe ser , capaz de representar los valores de todos los miembros de la enumeración.

No es que los compiladores son cualquier bueno siguiendo el estándar, pero en esencia: Si su enumeración tiene otra cosa que un int, que está en el "comportamiento no compatible que puede volver que muerde en un año o dos" de profundidad territorio.

+2

teniendo solo eso, lo siguiente es válido, creo: enum {LAST = INT_MAX, LAST1, LAST2}; entonces LAST2 no es representable en int, pero no había una expresión que lo definiera. –

+4

En el PDF real, define que: "Los identificadores en una lista de enumeradores se declaran como constantes que tienen tipo int [...]". He omitido eso para que no sea demasiado detallado. –

+2

Nota "* a * tipo entero con signo, o * un * tipo entero sin signo". No necesariamente 'int'. 'short' y' long' también son tipos enteros, y cualquiera que sea la implementación elegida, todos los valores deben ajustarse ("* deberá * ser capaz de representar los valores de todos los miembros de la enumeración"). –

12

Si bien las respuestas anteriores son correctas, algunos compiladores tienen opciones para romper el estándar y usar el tipo más pequeño que contendrá todos los valores.

Ejemplo con GCC:

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

En realidad, hasta donde puedo ver, esto no rompe el estándar. Como se explica en la respuesta de Michael Stum, el estándar permite al compilador elegir el tipo real de las enumeraciones, siempre que todos los valores quepan. – sleske

+1

He trabajado con compiladores MacOS C++ que explotan el rango limitado de valores en una enumeración para almacenarlos en tipos más pequeños. No recuerdo si fue Metrowerks Codewarrior o XCode. Esto está dentro del estándar C++. No puede suponer sizeof (MyEnum) == sizeof (int) en general. – persiflage

-3

considerar:

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

Esto le dará a la salida como 4. Así que no importa el número de elementos una enumeración contiene, su tamaño es siempre fija.

+4

La respuesta de Michael Stum es correcta. Esto es específico del compilador. Puedes probarlo tú mismo con IAR EWARM. IAR EWARM muestra 1 para su ejemplo. Si hay hasta 255 elementos, todavía se muestra 1. Después de agregar el elemento 256, sube a 2. – desowin

+5

La pregunta no es sobre C++. – Michas

0

El tamaño de almacenamiento no está influenciado por la cantidad de valores en la enumeración. El tamaño de almacenamiento está definido por la implementación, pero principalmente es el sizeof(int).

+2

No es cierto para todos los compiladores. Algunos compiladores eligen almacenar en un tipo más pequeño que se ajuste a los valores en esa enumeración particular. Véase más arriba. – persiflage

-1

No tenemos control sobre el tamaño de una variable enum. Depende totalmente de la implementación, y el compilador da la opción de almacenar un nombre para un entero usando enum, por lo que enum sigue el tamaño de un entero.

0

En lenguaje C, se garantiza que un enum tiene el tamaño de int. Hay una opción de tiempo de compilación (-fshort-enums) para que sea tan corta (Esto es principalmente útil en caso de que los valores no sean más de 64K). No hay opción de tiempo de compilación para aumentar su tamaño a 64 bits.

Cuestiones relacionadas