在C ++中,必须初始化引用变量。 int& a; //错误
static int &b; // Error
但是
extern int &c; // No error
为什么编译器没有为extern
说明符引用提供错误?
答案 0 :(得分:12)
extern
关键字是编译器的一个指令,您现在声明一个符号,该符号将在链接期间从另一个目标文件中获取。
初始化是在实际符号定义的地方进行的。
如果你有一个带
的a.c文件extern
带有
的b.c文件int foo;
int &bar = foo;
当你将文件b.c编译成b.o时,编译器会将extern int &bar;
的符号留空。链接程序时,链接器需要在a.o中找到导出的符号bar
,然后用a.o中的bar
替换b.o中的空白符号
如果链接器无法在链接的目标文件中的任何位置找到所需的符号,则会发出链接器错误(不是编译器错误)。
答案 1 :(得分:5)
为什么编译器没有为
<script> // HTAs don't have a console. console = {}; </script>
引用提供错误?
因为extern
不是定义,而只是声明。它通知编译器extern int &c;
将在程序中的其他位置定义。
cppreference page on "storage class specifiers"解释了此方案中c
的含义。
答案 2 :(得分:5)
语言规范明确说明
8.3.2参考文献
5 [...]引用声明应包含初始值设定项(8.6.3),除非声明包含显式extern
说明符(7.1.1),否则是类成员(9.2)在类定义中声明,或者是声明 参数或返回类型(8.3.5);见3.1。
此报价直接涵盖您的情况。换句话说,引用不会从一般声明定义规则中排除。您可以为其他地方定义(和初始化)的引用创建非定义声明。
没有人禁止您将初始值设定项包含在带有明确extern
关键字的引用声明中。但是,像往常一样,它会将非定义声明转换为定义。