2017-11-11 298 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關鍵字將初始化程序包含到引用聲明中。但是,像往常一樣,它會將一個非定義聲明變成一個定義定義