variable tipos tipo que enumerados enum ejemplo crear c++ c enums

c++ - tipos - ¿Se puede definir un enumerador en términos de otros enumeradores dentro del mismo tipo de enumeración?



typedef enum c ejemplo (4)

Aunque como ya se indicó, es perfectamente válido, hay una cosa que debe tener en cuenta: mientras se define un tipo de enumeración, en C ++, los enumeradores ya declarados pueden no tener el tipo exacto que está esperando. Como resultado, algo como

enum E { a = INT_MAX, b = UINT_MAX, c = a + 1, // error: overflow };

No es válido, aunque esto es:

enum E { a = INT_MAX, b = UINT_MAX, }; enum E2 { c = a + 1, // okay: a is promoted to unsigned int };

Para un ejemplo similar, la resolución de sobrecarga puede no comportarse como usted esperaría:

char f(int); template <typename T> char (&f(T))[2]; enum E { a = 0, b = sizeof(f(a)), // 1 }; enum E2 { c = sizeof(f(a)), // 2 };

Hay otros ejemplos similares que son algo poco intuitivos.

Para C, las reglas son un poco más simples. En C, el tipo de una constante de enumeración es independiente del tipo de enumeración, por lo que mi ejemplo de a + 1 no es válido incluso con el E2 . Esto lleva a hacer resultados consistentes.

Por el bien de la curiosidad, estoy experimentando esto:

enum RxqType { A = (1 << 0), B = (1 << 1), C = (A | B), D = A+B+C };

Los enumeradores C y D se definen en términos de enumeradores anteriores. Es inusual, así que no estoy seguro de si es seguro. No puedo encontrar ningún ejemplo al respecto a través de Google (aunque puede pasarse por alto).

Parece estar bien cuando printf o cout C y D en Visual C ++ 2013 y MinGW. Pero me preocupa si es de conformidad estándar y si desencadena comportamientos indefinidos.

¿Alguien puede responder a mi preocupación por la conformidad estándar y el comportamiento indefinido? ¿Y hay algo más que deba preocuparme?


Sí, 100% válido. Esto está bien, de hecho, apreciado.

enum RxqType { A = (1 << 0), B = (1 << 1), C = (A | B), D = A+B+C };


Sí, esto se trata en el borrador de la sección C99, sección 6.2.1 Ámbitos de los identificadores, que nos dice que cada enumerador está dentro del alcance una vez definido:

Cada constante de enumeración tiene un alcance que comienza justo después de la aparición de su enumerador de definición en una lista de enumeradores.

Esto se trata en el borrador del estándar de C ++, sección 3.3.2 Punto de declaración que dice:

El punto de declaración para una enumeración es inmediatamente después del identificador (si existe) en su especificador de enumeración (7.2) o su primera declaración de enumeración opaca (7.2), lo que ocurra primero.

y para completar, podemos ir a la sección 6.7.2.2 Especificadores de enumeración del borrador del estándar C99, que nos dice que un enumerador se puede configurar con una expresión constante y un enumerador en sí mismo es una expresión constante.

enumerator: enumeration-constant enumeration-constant = constant-expression

Lo que son expresiones constantes se trata en la sección 6.6 Expresiones constantes y nos dice que los enumeradores son constantes y también que las expresiones aritméticas de constantes enteras también son expresiones constantes.


enum RxqType { A = (1 << 0), B = (1 << 1), C = (A | B), D = A+B+C };

En C y en C ++ esto es válido.

Para C:

(C11, 6.2.1p7) "Cada constante de enumeración tiene un alcance que comienza justo después de la aparición de su enumerador de definición en una lista de enumeradores".

Para C ++:

(C ++ 11, 3.3.2p4) "El punto de declaración para un enumerador es inmediatamente después de su definición de enumerador".