Как непрозрачные и анонимные объявления enum соответствуют требованиям стандарта?

Я прочитал в N3936 (пункт 7.2.2) «Необязательный идентификатор не должен быть опущен в объявлении перечисления с ограниченным диапазоном», поэтому я попробовал следующий код
(где встроенные комментарии пытаются объяснить мою интерпретацию) как с
GNU-g ++ 4.8.3 и clang 3.4.2

 # include <iostream>

enum any : int; // unscoped opaque declaration :int required by the standard

enum : int  {a} t; // unscoped anonymous declaration of t (:int not required)

enum any : int {b} u; // redlecaration of type "any" with one enumerator

enum class foo : char; // scoped opaque declaration "foo" required, :char NOT

enum class foo : char {a, b} Foo; // redeclaration of "foo" with 2
// enumerators. now :char REQUIREDenum class : char {d} Enum; // scoped anonymous declaration of Enum
// wouldn't be disallowed?

int main()
{
t = a; // assignment to "t"u = b; // assignment to "u"Foo = foo::a; // assignment to "Foo"Enum = decltype(Enum)::d;  // allowed (??)
std::cout << static_cast<int>(t) << ' '
<< static_cast<int>(u) << ' '
<< static_cast<int>(Foo) << ' '
<< static_cast<int>(Enum) << std::endl;
}

clang отклоняет код и выдает сообщение об ошибке в объявлении Enum, в котором говорится, что «перечисление в области требует имени»; GNU-g ++ однако принимает
он выполняет установку четырех нулей на стандартный вывод (как и следовало ожидать, после запуска кода).

Обратите внимание, что clang выдает дополнительные ошибки, когда имя перечислителя «d»
изменилось на «а», как если бы в этом случае ошибочно объявленный Enum
быть перечислением с незаданной областью с именем «а», конфликтующим с тем же именем
в типе «любой» (по крайней мере, это то, что я интерпретировал, читая
диагностика). Вместо этого GNU-g ++ будет принимать (связно) также имя «a» для перечислителя Enum.

Так в чем правда?

4

Решение

Стандарт здесь довольно понятен. Код плохо сформирован.

GNU-g ++, однако, принимает его и выполняет установку четырех нулей на стандартный вывод (как и следовало ожидать, после запуска кода).

Это GCC ошибка 54216. Эта ошибка была исправлена ​​в GCC 4.9, которая отвергает ваш код, как и ожидалось.

Обратите внимание, что clang выдает дополнительные ошибки, когда имя перечислителя «d» изменяется на «a», как если бы в этом случае ошибочно объявленный Enum
будет перечисление с незаданной областью с именем «а», конфликтующим с
то же имя в типе «любой» (по крайней мере, это то, что у меня есть
интерпретировать чтение диагностики).

Clang, вероятно, предполагал, что вы действительно хотели объявить анонимного незаданной Перечисление и приступил к анализу оставшейся части кода на этом предположении.

3

Другие решения


По вопросам рекламы [email protected]