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

Czy ta pusta definicja enum jest przenośna? Kompiluje w gcc i i msvc.Czy puste enum (enum {};) jest przenośne?

+9

Co używasz go? – Cameron

+0

W makrze, które może mieć pusty parametr –

+0

To nie tylko puste wyliczenie, to anonimowe puste wyliczenie, które, jak powiedziano w innych odpowiedziach, jest źle sformułowane, ponieważ nie deklaruje niczego. Tak więc puste wyrazy są walidami, które nie są poprawne, są anonimowymi pustymi wyliczeniami. Możesz zadeklarować zarówno "enum {A}", jak i "enum e {}", które są prawidłowymi deklaracjami. –

Odpowiedz

8

takie wyliczenie jest wyraźnie wymienione w klauzuli 7 ust. 3 normy C++ jako źle sformułowane. gcc tego nie akceptuje. było naprawić błąd za to w gcc:

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

+1

Tęskniłem za tym. Gramatyka dopuszcza formularz, ale w nagłówku rozdziału znajduje się konkretny zakaz, w istocie, wszelkich deklaracji, które nie deklarują ani typu, ani encji (zmiennej, funkcji lub odniesienia). I podaje właśnie tę sprawę jako przykład. –

+2

@Nawaz Paragraf cytowany przez WeaselFox jest obecny w C++ 98, C++ 03 i C++ 11, niezmieniony iz tym dokładnym przykładem. –

4

Zgodnie z poniższym fragmencie z C++ standardzie możemy wywnioskować, że to jest rzeczywiście ważne stwierdzenie:

7,2/1 Wyliczenia wyliczeniowe (C++ 03)
...
Specyfikacja szczegółowa:
              enum identyfikator opt {wyliczający-lista opt}

Należy zauważyć, że zarówno identyfikator i wyliczający-lista są opcjonalne, a do nich oświadczenie enum {} jest ważny (jeśli zapytasz o standard).


Ale nie średnia powiedzieć również, że puste deklaracje są źle sformułowane?

Tak, istnieje nawet przykład enum { }; w poniższym fragmencie standardu.

/3 Projektanci (C++ 03)

W tych przypadkach, gdy klasa-specyfikator lub wyliczenia-specyfikator jest obecny w dekl-specyfikatora-seq identyfikatory w tych specyfikatorach należą do nazw zadeklarowanych przez deklarację (jako nazw klas, , nazw enum lub enumeratorów, w zależności od składni).

W takich przypadkach, a oprócz deklaracji nienazwanej bitowego pola (9,6) decl-specifier-nast powinien przedstawić jedną lub więcej nazw w program lub powinny redeclare nazwę wprowadzoną przez poprzednią deklarację .

* Przykład [

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

* Przykład end]


Wnioski

Stwierdzenie wydaje się chore - powstał po starannym spojrzeniu na standard, chociaż kompilatory są pisane przez ludzi - a ludzie często popełniają błędy, a czasem przeoczają rzeczy.


TL; DR Nie należy używać pustych deklaracji, takich jak enum { };, mimo że kompiluje

+0

Ale jak zauważył WeaselFox, istnieje ogólne ograniczenie semantyczne, dla deklaracji __all__, w §7/​​3, które skutecznie zabrania deklaracji , które nic nie deklarują. Jednym z podanych przykładów jest 'enum {};'. –

+0

@JamesKanze odpowiedź zaktualizowana, dziękuję za heads up, zupełnie zapomniałem o "7.1/3". –

+0

@refp Tęskniłem za nią, dopóki WeaselFox tego nie wskazał. (A sekcja to §7/​​3, a nie §7.1/3.) –