关于为什么枚举器的重新定义格式错误有什么规则吗?

Is there any rule about why is the redefinition of the enumerator ill-formed?

考虑这个例子

enum class A{
    a = 0,
    a = 1
};

compilers will report an error, which is the "redefinition of enumerator 'a'". However, [basic.def.odr#1]枚举器没有任何要求

No translation unit shall contain more than one definition of any variable, function, class type, enumeration type, template, default argument for a parameter (for a function in a given scope), or default template argument.

我想知道标准中的哪条规范规则对此有限制?

原回答

是的,截至目前,C++ 标准中的单一定义规则不包括枚举数。

然而,“第二个 a 是对第一个 a 的重新声明”的解释也不起作用。
[dcl.enum#nt:enumerator-list]我们可以知道,一个enumerator-list是一个enumerator-definition的列表,所以都是定义。

enumerator-list:
    enumerator-definition
    enumerator-list , enumerator-definition

为什么枚举数没有包含在一个定义规则中?这可能是标准委员会的疏忽。 考虑到在 C 中,枚举数 禁止重新定义。

来自 the draft of C99,第 6.7 节:

5

A declaration specifies the interpretation and attributes of a set of identifiers. A definition of an identifier is a declaration for that identifier that:
— for an object, causes storage to be reserved for that object;
— for a function, includes the function body;101)
— for an enumeration constant or typedef name, is the (only) declaration of the identifier.

从6.7.2.2节我们可以看出枚举数是一个枚举常量:

enumerator:
    enumeration-constant
    enumeration-constant = constant-expression

并且从 6.7.2.2 还可以推断,枚举器列表中的所有枚举器将始终不仅被声明而且定义

3

The identifiers in an enumerator list are declared as constants that have type int and may appear wherever such are permitted. An enumerator with = defines its enumeration constant as the value of the constant expression. If the first enumerator has no =, the value of its enumeration constant is 0. Each subsequent enumerator with no = defines its enumeration constant as the value of the constant expression obtained by adding 1 to the value of the previous enumeration constant. (The use of enumerators with = may produce enumeration constants with values that duplicate other values in the same enumeration.) The enumerators of an enumeration are also known as its members.

所以在C中,你不能多次定义同一个标识符的枚举数,因为如果可以,它将不再是标识符的唯一声明,这使得它成为一个无效的定义根据到第 6.7 节。

C 中的行为可能是几乎所有 C++ 编译器禁止重新定义枚举数的原因,并且它也可能是 C++ 的预期或预期行为。

更新

更新 2022-02-16:我已经按照 https://isocpp.org/std/submit-issue. It's been accepted and is now Issue 2530.[=19 中详述的程序提交了关于此问题的问题=]