我正在尝试了解enumeration constant
的链接,但在标准N1570
中找不到明确的答案。 6.2.2(p6)
:
以下标识符没有链接:声明为 除对象或功能以外的任何事物;声明的标识符 作为函数参数;对象的块作用域标识符 声明时没有存储类说明符
extern
。
因此,我需要了解常量不是对象。对象定义为3.15
:
执行环境中的数据存储区域,内容 可以代表值
也6.2.2(p4)
(强调我的意思):
对于在存储类说明符extern中声明的标识符 可以看到该标识符的先前声明的范围,31) 如果先前声明指定了内部或外部链接,则 后面声明中标识符的链接与 事先声明中指定的链接。 如果没有事先声明 可见,或者如果先前的声明未指定任何链接,则 标识符具有外部链接。
反正6.4.4.3(p2)
:
声明为枚举常量的标识符的类型为
int
。
结合所有我不明白的原因
enum test {
a = 1
};
extern int a; //compile-error. UB?
不编译吗?我希望a
具有外部链接。
该行为是否定义明确?您可以提供对标准的解释说明吗?
答案 0 :(得分:7)
声明为枚举常量的标识符的类型为int
这并不意味着它是int类型的变量
但是
extern int a;
说有一个名为 a 的 int 类型的变量,这与枚举常量冲突
为什么没有枚举常量没有链接
出于同样的原因,常数123(也具有类型 int ,但无论如何)也没有链接
答案 1 :(得分:2)
链接在这里无关紧要。在同一个编译单元中,您尝试具有两个相同的标识符。想象一下代码是否可以编译:
enum test {
a = 1
};
extern int a;
int b = a; // which `a`? a as the external variable or `a` as a constant? How to decide.
答案 2 :(得分:2)
在6.2.2 4中,该标准仅打算讨论对象和功能的标识符的链接,但未能阐明这一点。
枚举常量仅是值,而不是对象或函数,并且它们的标识符从不具有任何链接。
观察声明extern int a;
将a
声明为int
对象的标识符。 int
对象与int
值是不同的,因此名为a
的枚举常量不能与名为int
的{{1}}对象相同。因此,a
的声明即使在考虑链接之前也是无效的。