为什么 "extern int &c;" 工作正常?
Why does "extern int &c;" working fine?
在C++中,必须初始化引用变量。
诠释 &a; // 错误
static int &b; // Error
但是
extern int &c; // No error
为什么编译器不给出 extern
说明符引用的错误?
Why Compiler doesn't give an error for extern
reference?
因为extern int &c;
不是定义,只是声明。它通知编译器 c
将在程序的其他地方定义。
cppreference page on "storage class specifiers" 解释了 extern
在这种情况下的含义。
extern
关键字是编译器的指令,您现在正在声明一个符号,该符号将在链接期间填充,取自另一个目标文件。
初始化预计发生在定义实际符号的地方。
如果您有一个 a.c 文件
int foo;
int &bar = foo;
还有一个 b.c 文件
extern int &bar;
当您将文件 b.c 编译成 b.o 时,编译器会将 bar
的符号留空。链接程序时,链接器需要在 a.o 中找到导出的符号 bar
,然后用 a.o 中的 bar
替换 b.o 中的空白符号]
如果链接器无法在链接的目标文件中的任何地方找到所需的符号 - 将发出链接器错误(不是编译器错误)。
语言规范明确说明
8.3.2 References
5 [...] The declaration of a reference shall contain an initializer (8.6.3) except when the declaration contains an explicit extern
specifier (7.1.1), is a class member (9.2) declaration within a class definition, or is the declaration of
a parameter or a return type (8.3.5); see 3.1.
这句话直接涵盖了您的情况。换句话说,引用不排除一般声明定义规则。您可以为在别处定义(和初始化)的引用创建非定义声明。
没有人禁止您使用显式 extern
关键字将初始值设定项包含到引用声明中。但是,像往常一样,它会将非定义声明变成 definition.
在C++中,必须初始化引用变量。 诠释 &a; // 错误
static int &b; // Error
但是
extern int &c; // No error
为什么编译器不给出 extern
说明符引用的错误?
Why Compiler doesn't give an error for
extern
reference?
因为extern int &c;
不是定义,只是声明。它通知编译器 c
将在程序的其他地方定义。
cppreference page on "storage class specifiers" 解释了 extern
在这种情况下的含义。
extern
关键字是编译器的指令,您现在正在声明一个符号,该符号将在链接期间填充,取自另一个目标文件。
初始化预计发生在定义实际符号的地方。
如果您有一个 a.c 文件
int foo;
int &bar = foo;
还有一个 b.c 文件
extern int &bar;
当您将文件 b.c 编译成 b.o 时,编译器会将 bar
的符号留空。链接程序时,链接器需要在 a.o 中找到导出的符号 bar
,然后用 a.o 中的 bar
替换 b.o 中的空白符号]
如果链接器无法在链接的目标文件中的任何地方找到所需的符号 - 将发出链接器错误(不是编译器错误)。
语言规范明确说明
8.3.2 References
5 [...] The declaration of a reference shall contain an initializer (8.6.3) except when the declaration contains an explicitextern
specifier (7.1.1), is a class member (9.2) declaration within a class definition, or is the declaration of a parameter or a return type (8.3.5); see 3.1.
这句话直接涵盖了您的情况。换句话说,引用不排除一般声明定义规则。您可以为在别处定义(和初始化)的引用创建非定义声明。
没有人禁止您使用显式 extern
关键字将初始值设定项包含到引用声明中。但是,像往常一样,它会将非定义声明变成 definition.