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



在§7.5(C++14)中的示例中,可以找到:

enum {}; // ill-formed

但是,从技术上讲,我认为这个代码是有效的。enum {}是一个枚举说明符,因此它是一个类型说明符ecl说明符.因此,它是一种简单声明并省略了init声明符列表。这一点已被§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说明符seq在声明中没有引入任何名称:

typedef class {} A;

在C++14 FD中,就在您的示例上方,它解释了声明格式错误的原因:

简单声明中,可选的init声明符列表可以是仅在声明类(第9条)或枚举(7.2)时省略[…]

在这种情况下,decl说明符seq应引入一个或多个名称添加到程序中,或者应重新声明由之前的声明

因此

enum {} e;
enum {a};

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

你还提到了的报价

如果枚举器列表为空,则底层类型就像枚举有一个值为0的枚举器。

这是关于底层类型的声明,而不是枚举本身,因此与此无关。


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

A初始化声明符。是的,是-[dcl.dcl]/9:

如果decl说明符seq包含typedef说明符,则声明被称为typedef声明,每个声明的名称init声明符被声明为typedef名称

也就是说,根据这个定义,声明为typedef-names的名称是init声明符。因此,存在一个init声明符列表,并且我们上面的引用不适用。

如果你仔细阅读标准,你会发现很多东西在纯粹的语法层面上是可以接受的,但在文本中是禁止的。这只是这一基本理念的众多实例之一。

其中许多情况都非常明显。让我们考虑一个非常琐碎的问题:一个浮点数。使用类似于标准的语法表示法,我们可以得到以下内容:

"-"opt数字>opt"

那里的一切都是"可选的"。然而,这并不意味着虚无应该被视为一个数字。也不意味着(例如).e是一个有效的浮点数。这确实意味着,如果其他作品中有一些存在,几乎任何一件作品都可以省略。小数点前和小数点后都不需要数字,所以每个数字本身都是可选的——但其中一个必须存在,所以1..1都有效,但只有.无效。同样,.也是可选的——类似于1e50的内容是一个完全有效的浮点文字,尽管它在任何地方都不包含.

这些限制在与句法符号本身相关的文本中得到了表达。允许(或不允许)的东西必须建立在所有东西的基础上,而不仅仅是孤立的一部分。

标准中明确规定(7项声明)

  1. 。。。在这种情况下,除未命名位字段(9.6)的声明外,decl说明符seq应引入一个或多个names添加到程序中,或者应该重新声明由之前的声明

此申报

enum {};   // ill-formed 

不满足要求。它在程序中既没有引入任何名称。

至于typedef,则

7.1.3 typedef说明符1包含decl说明符的声明typedef声明稍后可以使用的标识符用于命名94)

最新更新