Подтвердить что ты не робот

GCC отклоняет простую декларацию с помощью enum-base; clang принимает его - что правильно?

GCC 4.9.2 не компилирует этот фрагмент, но clang 3.5.0. Какой из них правильный?

enum F : int { x, y, z};
int F;
enum F:int f = F::x;

Выход GCC:

main.cpp:3:12: error: expected ';' or '{' before 'f'
 enum F:int f = F::x;
            ^
main.cpp:3:12: error: expected class-key before 'f'
main.cpp:3:14: error: invalid type in declaration before '=' token
 enum F:int f = F::x;
              ^
main.cpp:3:16: error: 'F' is not a class, namespace, or enumeration
 enum F:int f = F::x;
                ^

Я считаю, что GCC верен, поскольку простая декларация (содержащая спецификатор специфицированного типа enum F) не позволяет enum-base (: int), но я хотел бы получить некоторое подтверждение.

4b9b3361

Ответ 1

Ваши рассуждения верны. Основание enum как ": int" синтаксически разрешено только в спецификаторе перечисления, который должен содержать список перечислений { с привязкой к скобкам } или в декларации непрозрачного enum, который должен следовать за перечислением, база с немедленной точкой с запятой ;.

Ответ 2

Я считаю, что gcc верен. Если мы посмотрим на правила грамматики в [dcl.enum], спецификатор типа приходит с:

перечислимой базы:
   : type-specifier-seq

Знаки, содержащие enum-base:

перечисление спецификатор:
  enum-head { enumerator-listopt }
  enum-head { list-list , }
перечислимого типа головки:
   enum-key атрибут-спецификатор-seqopt identifieropt enum-baseopt
   enum-key attribute-specifier-seqopt идентификатор вложенного имени-спецификатора Перечисление-baseopt

и

непрозрачного перечисление декларирование:
  enum-key атрибут-спецификатор-seqopt идентификатор enum-baseopt ;

Это выражение:

enum F:int f = F::x;

Не существует ни спецификатора перечисления (нет {}), ни декларации opaque-enum (в котором спецификатор типа сразу будет следовать ;). Поскольку это не в грамматике С++, это не допустимое выражение.