studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones c++ c++11 enums forward-declaration

c++ - programacion - ¿Por qué debe proporcionarse el tamaño de una enumeración cuando se declara hacia adelante?



manual de programacion android pdf (2)

Simplemente no puedo ver por qué el tamaño de la enumeración es relevante para el compilador mientras que el tamaño de la clase no lo es.

Mi ejemplo de código:

class A; enum E; // must be enum E : int; in order to compile void f(const A & param); void f(const E & param);

Estoy hablando aquí de compiladores de C ++ estándar. Sé que MSVC deja que se compile y funciona bien. Así que la pregunta es:

¿Por qué esto no ha sido estandarizado?


Es una diferencia en los objetivos de diseño.

La declaración directa de una clase crea un tipo incompleto que se puede usar de forma opaca en los punteros / referencias. Esta es una propiedad muy útil.

Un tipo de enumeración incompleta no es tan útil. Sin embargo, poder declarar una enumeración sin declarar qué constantes están dentro de esa enumeración es útil. La complejidad que proviene de un tipo de enumeración incompleta se puede evitar al requerir que se especifique el tamaño.

Así que mi mejor conjetura es que los implementadores del compilador se tuvieron en cuenta cuando se diseñó esta característica, y el comité descubrió que la mayor complejidad de las enumeraciones incompletas no valía la pena.


Esto se ha estandarizado, la propuesta 2764: Declaración de enumeración hacia adelante (rev. 3) permitió la declaración de enumeración hacia adelante si especifica el tipo subyacente, mientras que antes no era posible.

La razón principal es que cuando no se especifica el tipo subyacente, el tamaño se define por la implementación y puede depender de los valores del enumerador. Del borrador de la norma C ++ 11, sección 7.2 [dcl.enum] :

Para una enumeración cuyo tipo subyacente no es fijo, el tipo subyacente es un tipo integral que puede representar todos los valores del enumerador definidos en la enumeración. Si ningún tipo de integral puede representar todos los valores del enumerador, la enumeración está mal formada. Está definido por la implementación qué tipo de integral se usa como tipo subyacente, excepto que el tipo subyacente no será más grande que int, a menos que el valor de un enumerador no se ajuste a un int o un unsigned int. Si la lista de enumeradores está vacía, el tipo subyacente es como si la enumeración tuviera un solo enumerador con valor 0.

Cuando se pasa por valor, tiene sentido que no saber el tipo subyacente sea un problema, pero ¿por qué es un problema cuando se trata de un puntero o una referencia? Esto importa ya que aparentemente en algunas arquitecturas, char * e int * pueden tener diferentes tamaños como se menciona en esta discusión de comp.lang.c ++: GCC y declaración de enumeración en adelante :

[...] Si bien en la mayoría de las arquitecturas puede no ser un problema, en algunas arquitecturas el puntero tendrá un tamaño diferente, en caso de que sea un puntero de carácter. Así que, finalmente, nuestro compilador imaginario no tendría idea de qué poner allí para obtener un ColorsEnum * [...]

Tenemos la siguiente respuesta de para referencia, que describe el caso en el que char * puede ser más grande que int * , lo que respalda la afirmación en la discusión anterior.

Algunos detalles más sobre los posibles tamaños de punteros que parecen char * y void * son las dos excepciones principales aquí, por lo que otros punteros a objetos no deberían tener los mismos problemas. Así que parece que este caso termina siendo único para los enums.