【问题标题】:Extern variable declaration does not have internal linkage外部变量声明没有内部链接
【发布时间】:2015-06-09 01:45:58
【问题描述】:

我问这个问题是 this 帖子的后续问题。他们说extern 块声明有外部链接而不是内部链接,但我不知道为什么:

static int i = 0; // #1
void g() {
    extern int i; // #3 external linkage
}

为什么extern 声明不采用i 的链接(内部链接)?帖子中的引用似乎允许这样做。在 OP 引用之后的示例中,它具有:

static void f();
void g() {
    extern void f(); // internal linkage
    // ...
}

它说外部声明具有内部链接。为什么使用变量和函数有区别?

【问题讨论】:

标签: c++ linkage


【解决方案1】:

因为变量“i”具有静态存储。所以,就你的 sn-p 而言,

  • 省略“静态”语句将产生“无链接”
  • 应用“静态”语句将产生“外部链接”(因为静态存储是 C/C++ 运行时基础架构中非常特殊的部分)。

此外,您可能会发现这个讨论很有趣: Understanding static storage class in C

【讨论】:

  • 我所知道的唯一具有外部链接的static 变量是类的静态数据成员。 static 局部变量没有链接,static 命名空间范围的变量有内部链接。
  • 再次查看 §3.5p6 中给出的示例解释,诀窍是双重的。如果特定静态变量与“extern”声明匹配,则它显示为外部链接。如果没有匹配这样的“extern”声明,则该静态变量将没有链接。这就是为什么我说静态存储“非常特别”,因为这里有一些不明显的技巧。
  • 请参阅 §3.5p9 和 CWG 426extern int i; (#3) 与 static int i; (#1) 所指的实体不同。
  • 为什么?链接器成功地将它们解析为同一个实体(否则它可能会抛出关于格式错误的程序的消息)。
  • 您无法从任何链接器的行为中推断出标准规定的内容。链接器可能包含错误,它们可能只是不符合 C++ 标准。 CWG 426 表示 C++ 标准委员会认为当前规范存在缺陷。当前规范(由委员会解释)说#1 和#3 应该是不同的实体。委员会(CWG)认为这个例子应该有未定义的行为或者是一个错误。
猜你喜欢
  • 2012-02-06
  • 2018-01-25
  • 1970-01-01
  • 2013-03-23
  • 1970-01-01
  • 2011-04-10
  • 2016-12-05
  • 2020-10-17
相关资源
最近更新 更多