2012-03-20 19 views
5
class Test 
{ 
    enum{}; 
    ... 
}; 

¿Es esta definición enum vacía portátil? Compila en gcc y y msvc.¿Está vacío enum (enum {};) portátil?

+9

¿Qué estás utilizando para? – Cameron

+0

En una macro que puede tener un parámetro vacío –

+0

Que no es simplemente una enumeración vacía, es una enumeración vacía anónima, que, como se dice en las otras respuestas, está mal formada porque no declara nada. Por lo tanto, las enumeraciones vacías son válidas, que no son válidas son enumeraciones vacías anónimas. Puede declarar tanto 'enum {A}' como 'enum e {}', que son declaraciones válidas. –

Respuesta

8

tal enumeración se enumera específicamente en la cláusula 7 párrafo 3 del estándar de C++ como mal formado. gcc no lo acepta. hubo una corrección de errores para esto en gcc:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29018

+1

Me había perdido eso. La gramática permite la forma, pero en el encabezado del capítulo, hay una prohibición específica de, en efecto, cualquier declaración que no declara ni un tipo ni una entidad (variable, función o referencia). Y da precisamente este caso como ejemplo. –

+2

@Nawaz El párrafo citado por WeaselFox está presente en C++ 98, C++ 03 y C++ 11, sin cambios y con este ejemplo exacto. –

4

acuerdo con el siguiente fragmento de la norma C++ se puede deducir que es de hecho una declaración válida:

7,2/1 declaraciones de enumeración (C++ 03)
...
enumeración especificador:
              enumeración identificador opt {empadronador lista opt}

Tenga en cuenta que tanto el identificador y el empadronador lista son opcionales, y por lo tanto una declaración enum {} es válido (si solicita el estándar).


Pero no la norma también decir que se forman los malos declaraciones vacías?

Sí, e incluso hay un ejemplo de enum { }; en el siguiente fragmento del estándar.

/3 especificadores (C++ 03)

En estos casos y siempre que una clase-especificador o enum-especificador es presente en la decl-especificador-seq, los identificadores en estos especificadores se encuentran entre los nombres declarados por la declaración (como class- nombres, nombres de enumeración o enumeradores, según la sintaxis).

En tales casos, y con excepción de la declaración de un campo de bits sin nombre (9,6), la decl-especificador-ss deberá introducir uno o más nombres en el programa, o se redeclare un nombre introducido por una declaración previa .

* Ejemplo [

enum { };   // ill-formed 
typedef class { }; // ill-formed 

* ejemplo final]


Conclusión

La afirmación parece estar enfermo -formado después de una cuidadosa mirada al estándar, aunque los compiladores están escritos por humanos, y los humanos tienden a cometer errores y algunas veces pasan por alto las cosas.


TL; DR Usted no debe usar una declaración vacía como enum { };, a pesar de que compila

+0

Pero, como señaló WeaselFox, existe una restricción semántica general, para __all__ declaraciones, en §7/​​3, que efectivamente prohíbe las declaraciones que no declaran nada. Uno de los ejemplos que proporciona es 'enum {};'. –

+0

@JamesKanze respuesta actualizada, gracias por el aviso que me olvidé por completo de '7.1/3'. –

+0

@refp También me lo había perdido, hasta que WeaselFox lo señaló. (Y la sección es §7/​​3, no §7.1/3.) –