是否有任何关于为什么重新定义枚举器格式错误的规则?
考虑这个例子
enum class A{
a = 0,
a = 1
};
该编译器会报告错误,这是“枚举‘一’的重新定义”。但是,[basic.def.odr#1]对枚举器没有任何要求
没有翻译单元应包含一个以上定义的任何变量,函数,类型,枚举类型,模板,默认参数为一个参数(用于在给定范围的函数)的,或缺省的模板参数。
我想知道标准中的哪个规范规则限制了它?
回答
是的,截至目前,C++ 标准中的单一定义规则不包括枚举器。
但是,“第二个a是第一个的重新声明a”的解释也不起作用。
从[dcl.enum#nt:enumerator-list]我们可以知道enumerator-list是enumerator-definition的列表,所以它们都是定义。
enumerator-list:
enumerator-definition
enumerator-list , enumerator-definition
为什么枚举器不包含在一个定义规则中?这可能是标准委员会的疏忽。考虑到在 C 中,枚举数被禁止重新定义。
来自C99 的草案,第 6.7 节:
5
声明指定了一组标识符的解释和属性。标识符的定义是对该标识符的声明:
— 对于对象,导致为该对象保留存储;
— 对于函数,包括函数体;101)
— 对于枚举常量或 typedef 名称,是标识符的(唯一)声明。
从 6.7.2.2 节我们可以看到一个枚举器是一个枚举常量:
enumerator:
enumeration-constant
enumeration-constant = constant-expression
从 6.7.2.2 还可以推断,枚举器列表中的所有枚举器将始终不仅被声明而且还被定义。
3
枚举器列表中的标识符被声明为具有 int 类型的常量,并且可以出现在任何允许的地方。带有 =的枚举器将其枚举常量定义为常量表达式的值。如果第一个枚举器没有 =,则其枚举常量的值为 0。每个后续没有 = 的枚举器将其枚举常量定义为前一个枚举常量的值加 1 得到的常量表达式的值。(将枚举数与 = 一起使用可能会产生枚举常量,其值与同一枚举中的其他值重复。)枚举的枚举数也称为其成员。
因此,在 C 中,您不能多次定义具有相同标识符的枚举数,因为如果可以,它将不再是标识符的唯一声明,这使其成为根据第 6.7 节无效的定义。
C 中的行为可能是几乎所有 C++ 编译器禁止重新定义枚举器的原因,这也可能是 C++ 的预期或预期行为。