¿Enumeración nunca debe utilizarse en una API?

Estoy usando una biblioteca de C que se me ha proporcionado ya comstackda. Tengo información limitada sobre el comstackdor, la versión, las opciones, etc., que se usa al comstackr la biblioteca. La interfaz de la biblioteca usa enum tanto en estructuras que se pasan como directamente como parámetros pasados.

La pregunta es: ¿cómo puedo asegurar o establecer que cuando compilo el código para usar la biblioteca provista, mi comstackdor usará el mismo tamaño para esas enum ? Si no lo hace, las estructuras no se alinearán, y el paso de parámetros puede estar desordenado, por ejemplo, long vs. int .

Mi preocupación proviene del estándar C99, que establece que el tipo de enum :

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 ser capaz de representar los valores de todos los miembros de la enumeración.

Por lo que puedo decir, siempre que el valor más grande se ajuste, el comstackdor puede elegir cualquier tipo que le guste, efectivamente en un capricho, que puede variar no solo entre los comstackdores, sino también con diferentes versiones del mismo comstackdor y / o opciones del comstackdor. . Podría seleccionar representaciones de 1, 2, 4 u 8 bytes, lo que resultaría en posibles incompatibilidades tanto en la estructura como en el paso de parámetros. (También podría seleccionar firmado o sin firmar, pero no veo un mecanismo para que eso sea un problema en este contexto).

¿Me estoy perdiendo de algo? Si no me falta algo, ¿significa esto que nunca debería usarse enum en una API?

Actualizar:

Sí, me faltaba algo. Si bien la especificación de idioma no ayuda aquí, como lo señala @Barmar, la Interfaz Binaria de la Aplicación (ABI) sí lo hace. O si no lo hace, entonces el ABI es deficiente. El ABI para mi sistema de hecho especifica que una enum debe ser un entero de cuatro bytes con signo. Si un comstackdor no obedece eso, entonces es un error. Dado un ABI completo y comstackdores compatibles, la enum se puede usar de forma segura en una API.

Las API que utilizan enumeración dependen de la suposición de que el comstackdor será coherente, es decir, dada la misma statement de enumeración, siempre elegirá el mismo tipo subyacente.

Si bien el estándar de lenguaje no requiere específicamente esto, sería bastante perverso para un comstackdor hacer cualquier otra cosa.

Además, todos los comstackdores para un sistema operativo en particular deben ser consistentes con el ABI del sistema operativo. De lo contrario, tendría muchos más problemas, como la biblioteca que usa int 64 bits, mientras que la persona que llama usa int 32 bits. Idealmente, el ABI debería restringir la representación de las enum para garantizar la compatibilidad.

De manera más general, la especificación de lenguaje solo garantiza la compatibilidad entre progtwigs comstackdos con la misma implementación. El ABI asegura la compatibilidad entre progtwigs comstackdos con diferentes implementaciones.

De la pregunta:

El ABI para mi sistema de hecho especifica que una enumeración debe ser un entero de cuatro bytes con signo. Si un comstackdor no obedece eso, entonces es un error.

Estoy sorprendido por eso. Sospecho que en realidad su comstackdor seleccionará un tamaño de 64 bits (8 bytes) para su enumeración si define una constante enumerada con un valor mayor que 2 ^ 32.

En mis plataformas (MinGW gcc 4.6.2 que apunta a x86 y gcc 4, .4 en Linux que apunta a x86_64), el siguiente código dice que obtengo enums de 4 y 8 bytes:

 #include  enum { a } foo; enum { b = 0x123456789 } bar; int main(void) { printf("%lu\n", sizeof(foo)); printf("%lu", sizeof(bar)); return 0; } 

-Wall -std=c99 con -Wall -std=c99 switches.

Supongo que se podría decir que esto es un error del comstackdor. Pero las alternativas de eliminar el soporte para las constantes enumeradas mayores de 2 ^ 32 o usar siempre enums de 8 bytes parecen indeseables.

Dado que estas versiones comunes de GCC no proporcionan una enumeración de tamaño fijo, creo que la única acción segura en general es no usar enumeraciones en las API.

Notas adicionales para GCC

La comstackción con “-pedantic” hace que se generen las siguientes advertencias:

 main.c:4:8: warning: integer constant is too large for 'long' type [-Wlong-long] main.c:4:12: warning: ISO C restricts enumerator values to range of 'int' [-pedantic] 

El comportamiento se puede adaptar a través de los conmutadores –short-enums y –no-short-enums.

Resultados con Visual Studio

La comstackción del código anterior con VS 2008 x86 provoca las siguientes advertencias:

 warning C4341: 'b' : signed value is out of range for enum constant warning C4309: 'initializing' : truncation of constant value 

Y con VS 2013 x86 y x64, solo:

 warning C4309: 'initializing' : truncation of constant value