¿Cuál es el tamaño de una enumeración en C?

8 minutos de lectura

Estoy creando un conjunto de valores de enumeración, pero necesito que cada valor de enumeración tenga 64 bits de ancho. Si no recuerdo mal, una enumeración generalmente tiene el mismo tamaño que un 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?

  • Entonces, si entiendo bien, ¿2 ^ 32 enumeraciones no son suficientes para usted? ¿O es un problema de alineación? ¿Por qué necesita que sean 64 en lugar de 32? Tengo mucha curiosidad.

    – jokoon

    6 mayo 2012 a las 14:27

  • @jokoon: Sinceramente, ya no recuerdo. Creo que quería que las enumeraciones contuvieran valores mayores que 2^32-1.

    – mipadi

    04/01/2013 a las 17:37

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

    – Demi

    21 de diciembre de 2013 a las 1:03

  • Una consideración importante en el tamaño de enum es de hecho el uso de la memoria. ¿La optimización de la memoria está muerta o algo así, o todos piensan que el compilador es el centro del universo todavía y automáticamente hace que todo sea rápido y óptimo sin ningún esfuerzo por parte del programador? Es absurdo usar un tipo de datos más grande del que necesita, y si solo necesito 256 valores o menos para mi enumeración, ¿por qué necesito palabras de 16 o 32 bits para almacenarlos? (El modelo de datos no es una excusa. Por lo general, los valores se extienden fácilmente con signos, como cuando se almacenan en los registros).

    – AMDG

    5 mayo 2021 a las 18:17


avatar de usuario
Michael Stum

Tomado del estándar C actual (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 debe ser una expresión constante entera que tenga un valor representable como un int.
[…]

Cada tipo enumerado será compatible con char, un tipo entero con signo o un tipo entero sin signo. La elección del tipo está definida por la implementación, pero debe poder representar los valores de todos los miembros de la enumeración.

No es que los compiladores sean buenos para seguir el estándar, pero esencialmente: si su enumeración contiene algo más que un int, está en un profundo “comportamiento no compatible que puede volver a morderlo en un año o dos”. territorio.

Actualización: el último borrador disponible públicamente del Estándar C (C11): http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1570.pdf contiene las mismas cláusulas. Por lo tanto, esta respuesta sigue siendo válida para C11.

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

    – Johannes Schaub – litb

    14 de diciembre de 2008 a las 1:33

  • 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.

    – Michael Stum

    14 de diciembre de 2008 a las 1:36

  • Nota “un tipo entero con signo, o un tipo entero sin signo”. No necesariamente int. short y long son tipos enteros también, y cualquiera que sea la implementación, todos los valores deben encajar (“deberá ser capaz de representar los valores de todos los miembros de la enumeración”).

    usuario824425

    18/02/2016 a las 17:45


  • Incapaz: constante de enumeración y tipo enumerado no es lo mismo. Los primeros son el contenido de la lista de declaración de enumeración, el último es la variable real. Entonces, mientras que las constantes de enumeración deben ser int, la variable de enumeración real podría ser de otro tipo. Esta es una inconsistencia bien conocida en el estándar.

    – Lundin

    25 de septiembre de 2017 a las 11:56


  • Para aclarar el punto de Lundin: Para enum my_enum { my_value }, my_value tendrá tipo intpero enum my_enum puede tener un tipo definido de implementación que debe representar al menos todos los valores de enumeración. Asi que my_value puede tener una conversión estrecha a enum my_enumpero está garantizado que no se desbordará.

    – P O’Conbhui

    26 de noviembre de 2017 a las 16:41


avatar de usuario
roberto apuesta

Un enum sólo se garantiza que sea lo suficientemente grande como para contener int valores. El compilador es libre de elegir el tipo real utilizado en función de las constantes de enumeración definidas, por lo que puede elegir un tipo más pequeño si puede representar los valores que defina. Si necesita constantes de enumeración que no encajan en un int necesitará usar extensiones específicas del compilador para hacerlo.

  • Tu primera oración parece estar en conflicto con la última. ¿Es la restricción 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 debería ser “An enum sólo se garantiza que encaje en un int valor.”

    – Haskell Elefante

    20 de junio de 2014 a las 9:23

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

    – persiflage

    23/09/2016 a las 19:37

  • Esta respuesta parece sugerir que una enumeración es tan grande como una int. La respuesta de Michael Stum, que hace referencia a C99, dice que una enumeración puede ser tan pequeña como un char.

    – Frank Kusters

    15 de septiembre de 2017 a las 6:46


  • La primera oración de esta respuesta es incorrecta. Él enum solo se garantiza que sea lo suficientemente grande como para contener el valor del enumerador más grande en la enumeración.

    –MM

    28 de septiembre de 2018 a las 8:11

  • @MM, tenía la intención de mantener un máximo de int valores. Es una afirmación correcta. Su declaración es realmente incorrecta. Un enum no contendrá el enumerador más grande si ese enumerador es más grande que un int. Aprendí esto al truncar mi enumerador de 64 bits al máximo de int (que es de 32 bits en mi caso).

    – SO_fix_the_vote_sorting_bug

    5 de junio de 2021 a las 13:57

avatar de usuario
kevin cox

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 CCG (documentación en el manual del CCG):

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

  • En realidad, por lo que puedo ver, esto no rompe el estándar. Como se explica en la respuesta de Michael Stum, el estándar permite que el compilador elija el tipo real de las enumeraciones, siempre que todos los valores se ajusten.

    – sleske

    7 sep 2015 a las 10:27

  • 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 era Metrowerks Codewarrior o XCode. Esto está dentro del estándar C++. No puede asumir sizeof(MyEnum) == sizeof(int) en general.

    – persiflage

    23/09/2016 a las 19:29

avatar de usuario
scirdan

Simplemente establezca el último valor de la enumeración en un valor lo suficientemente grande como para que tenga el tamaño que le gustaría que tuviera la enumeración, entonces debería tener ese tamaño:

enum value{a=0,b,c,d,e,f,g,h,i,j,l,m,n,last=0xFFFFFFFFFFFFFFFF};

avatar de usuario
Miguel

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

avatar de usuario
ss ana

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

avatar de usuario
ss ana

Considere este código:

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

Dará 4 como salida. Así que no importa el número de elementos y enum contiene, su tamaño siempre es fijo.

  • La respuesta de Michael Stum es correcta. Esto es específico del compilador. Puede probarlo usted mismo con IAR EWARM. IAR EWARM muestra 1 para su ejemplo. Si hay hasta 255 artículos, todavía muestra 1. Después de agregar el artículo 256, sube a 2.

    – desowin

    25 de noviembre de 2015 a las 7:43

  • La pregunta no es sobre C++.

    – Michas

    31 de agosto de 2016 a las 23:12

  • Cosas importantes a tener en cuenta antes de escribir más C o C++: El hecho de que compile no significa que sea legal según el Estándar. El hecho de que obtenga un resultado dado no significa que el Estándar diga que siempre lo obtendrá o que otros usuarios lo harán cuando ejecuten su código. Preguntas como esta necesitan una respuesta que haga referencia al Estándar o al menos especificación definida por la implementación para un compilador/ABI determinado. Simplemente compilar y ejecutar un programa y ver un resultado en un día no transmite ninguna lección sobre tales preguntas (y muy poco sobre cualquier otra cosa).

    – subrayado_d

    16/09/2018 a las 16:20

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad