空的,未命名的枚举说明符的合法性

Bel*_*loc -3 c++ language-lawyer c++11 c++14

在§7.5(C++ 14)的例子中,我发现:

enum {}; // ill-formed

但是,从技术上讲,我认为代码是有效的.enum {}是一个枚举说明符,因此,它是一个类型说明符,它是一个decl-specifier,因此,它是一个带有省略的init-declarator-list简单声明.这被§7.5接受.请注意,对于未作用域的枚举,标识符是可选的.此外,clang编译此警告.

编辑

关于提到的答案the *decl-specifier-seq* shall introduce one or more names into the program, or shall redeclare a name introduced by a previous declaration,我在下面展示了一个编译的typedef声明,但是其decl-specifier-seq在声明中没有引入任何名称:

typedef class {} A;
Run Code Online (Sandbox Code Playgroud)

Col*_*mbo 7

在C++ 14 FD中,正好在你的例子之上,它解释了为什么声明格式不正确:

在一个简单声明中,只有在声明一个类(第9节)或枚举(7.2)[...]时,才能省略可选的init-declarator-list.

在这种情况下,DECL说明符-SEQ应引入一个或多个名称到程序,或应重新声明由先前声明引入的名称.

于是

enum {} e;
enum {a};
Run Code Online (Sandbox Code Playgroud)

是有效的 - 我们的引用不适用于第一个声明,因为它包含一个init-declarator,第二个引用该名称a作为枚举器.请注意,GCC不会编译第一个声明,这可能是一个错误.

你还提到了引用

如果枚举器列表为空,则基础类型就好像枚举具有值的单个枚举器一样0.

这会声明基础类型,而不是枚举本身,因此与此无关.


为什么typedef class {} A;编译?

Ainit-declarator.是的,它是 - [dcl.dcl]/9:

如果decl-specifier-seq包含typedef说明符,则声明称为typedef声明,并且每个init声明的名称 声明typedef-name

即,声明为typedef-names的名称init-declarators,由此定义.因此有一个init-declarator-list,我们的上述引用不适用.