关于为什么枚举器的重新定义格式错误有什么规则吗?
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 中详述的程序提交了关于此问题的问题=]
考虑这个例子
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 中详述的程序提交了关于此问题的问题=]