【问题标题】:Why does "extern int &c;" working fine?为什么“extern int &c;”工作正常吗?
【发布时间】:2017-11-11 12:35:16
【问题描述】:

在 C++ 中,必须初始化引用变量。 诠释&a; // 错误

static int &b; // Error

但是

extern int &c; // No error

为什么编译器没有给出extern 说明符引用的错误?

【问题讨论】:

  • 因为在外部定义中强制初始化。
  • extern 位告诉编译器 c 在其他地方声明/定义
  • @rsp extern int &c;不是参考的定义。它只是一个没有定义的声明。
  • extern int &peach; string toad = "but our princess is in another castle";
  • 考虑如果可能会发生什么。现在链接器必须弄清楚当 extern 声明和实际声明没有相同的初始化程序时要做什么。链接器没那么聪明。

标签: c++ variables reference extern


【解决方案1】:

extern 关键字是编译器的一个指令,您现在声明一个将在链接期间填充的符号,取自另一个目标文件。 初始化预计发生在实际符号被定义的地方。

如果你有一个带有的 a.c 文件

int foo;
int &bar = foo;

还有一个 b.c 文件

extern int &bar;

当您将文件 b.c 编译为 b.o 时,编译器会将 bar 的符号留空。链接程序时,链接器需要在a.o中找到导出的符号bar,然后将b.o中的空白符号替换为a.o中的bar

如果链接器在链接的目标文件中的任何位置都找不到所需的符号 - 将发出链接器错误(不是编译器错误)。

【讨论】:

    【解决方案2】:

    为什么编译器没有给出extern 引用的错误?

    因为extern int &c; 不是一个定义,而只是一个声明。它通知编译器c 将在程序的其他地方定义。

    cppreference page on "storage class specifiers" 解释了extern 在这种情况下的含义。

    【讨论】:

      【解决方案3】:

      语言规范明确说明

      8.3.2 引用
      5 [...] 引用的声明应包含初始化程序 (8.6.3),除非声明包含显式 extern 说明符 (7.1.1),是类定义中的类成员 (9.2) 声明,或者是 参数或返回类型(8.3.5);见 3.1。

      这句话直接涵盖了您的情况。换句话说,引用不被排除在一般声明-定义规则之外。您可以为在别处定义(和初始化)的引用创建非定义声明。

      没有人禁止您在带有显式 extern 关键字的引用声明中包含初始化程序。然而,像往常一样,它会将一个非定义的声明变成一个定义

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-18
        • 1970-01-01
        相关资源
        最近更新 更多