2017-11-11 297 views
6

在C++中,引用变量必须被初始化。 int&a; //错误为什么“extern int&c;”工作正常吗?

static int &b; // Error 

extern int &c; // No error 

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

+2

因为初始化被迫在外部定义中发生。 – user0042

+3

'extern'位告诉编译器'c'被声明/定义在其他地方 –

+4

@rsp extern int&c;不是一个参考的定义。这只是一个没有定义的声明。 –

回答

12

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

如果您在编译文件b.c到B.O编译器将离开符号bar空与

int foo; 
int &bar = foo; 

的交流转换器文件,并

extern int &bar; 

一个b.c文件。当链接程序,链接器将需要找到出口符号bar在AO并再与bar从AO

更换空白符号博如果连接器无法找到所需的符号随时随地链接对象文件 - 将发布链接器错误(不是编译器错误)。

5

为什么编译器不提供extern参考的错误?

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

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

5

语言规范明确地说

8.3.2参考
[...]一个引用的声明应包含在报关的时候包含了除一个初始化(8.6.3)一个明确的extern说明符(7.1.1),是类定义中的类成员(9.2)声明,或是参数或返回类型(8.3.5)的声明 ;见3.1。

您的情况直接由此报价覆盖。换句话说,引用不是从通用声明定义规则中排除的。您可以在其他地方为已定义(和已初始化)的引用创建非定义声明。

没有人禁止您使用明确的extern关键字将初始化程序包含到引用声明中。但是,像往常一样,它会将一个非定义声明变成一个定义定义