【问题标题】:Why do enumeration constants have no linkage?为什么枚举常量没有链接?
【发布时间】:2019-06-21 04:54:16
【问题描述】:

我试图了解enumeration constants 的链接,但在标准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 有外部链接。

LIVE DEMO

行为是否明确?您能否提供参考标准来解释这一点?

【问题讨论】:

  • 你的问题没有任何意义。你只是尝试在同一个编译单元中有两个相同的符号。
  • @P__J__ 你的问题没有任何意义 为什么?我提供了行为并询问了它的解释?它是明确定义/未定义/未指定的行为吗?
  • 它和int a; extern int a; 一样,为什么不编译。在一个编译单元中完全相同的两个相同符号。它与链接没有任何共同之处。
  • 某物可以有一个标识符而不是一个对象。枚举常量与整数常量123 和字符常量'A' 属于同一类别。
  • @SomeName 如果您不同意,您需要编写自己的编译器。

标签: c enums language-lawyer extern


【解决方案1】:

链接在这里无关紧要。在同一个编译单元中你尝试有两个相同的标识符想象一下如果代码编译:

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.

【讨论】:

  • 那么这是什么意思:如果前面的声明没有指定链接,那么标识符有外部链接
  • @SomeName 它没有。当联系很重要时,您还没有进入舞台
  • 但他们说的是“标识符的链接”,而不是引用对象或函数的标识符的链接。所以我得出结论,链接的概念可以应用于任何标识符(不仅仅是指对象或函数,在这种情况下标识符没有链接)
【解决方案2】:

在 6.2.2 4 中,该标准打算仅讨论对象和函数标识符的链接,但没有明确说明。

枚举常量只是值,而不是对象或函数,它们的标识符永远不会有任何联系。

注意声明 extern int a;a 声明为 int 对象的标识符。 int 对象与int 值不同,因此名为a 的枚举常量不能与名为intint 对象相同。所以extern int a;的声明即使在考虑链接之前也是无效的。

【讨论】:

  • 其实我并没有发现 thr 链接的概念只适用于对象或函数。
【解决方案3】:

声明为枚举常量的标识符具有 int 类型

这并不意味着它是 int 类型的变量

但是

extern int a;

表示有一个int类型的变量名为a,这是与枚举常量冲突


为什么没有枚举常量没有链接

出于同样的原因,常量 123(也有 int 类型,但无论如何)也没有链接

【讨论】:

  • 能给个参考吗?它是明确定义的还是未定义的行为?
  • @bruno 您尝试回答错误的问题。联动并不重要。他只是在同一个编译单元中有两个相同的符号。我不会编译
  • @P__J__ 是的,我知道,这就是我说存在冲突的原因。但我想你不明白他的问题,显然他想象枚举常量有一个链接,而另一个文件中的extern int a; 允许访问它
  • 这是在另一个阶段链接。与编译器无关:)
猜你喜欢
  • 2020-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-11
  • 2015-11-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多