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
), но я хотел бы получить некоторое подтверждение.
Ответы
Ответ 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 (в котором спецификатор типа сразу будет следовать ;
). Поскольку это не в грамматике С++, это не допустимое выражение.