2017-01-27 348 views
0

比方說,我有一個C以下設置++程序,在全球/命名空間範圍(以外的任何塊):EXTERN常量,這是聲明,這是向前聲明

情況1:

a.cpp

extern const int i=5; 

b.cpp

extern const int i; 

有兩種方式,在我的腦海裏,編譯器可以看到這一點。一個是,真正的聲明是在b.cpp中,而a.cpp只有一個前向聲明和初始化。 (因爲我們知道,對於特定的外部常量,在聲明時不需要初始化)編譯器可能生成的其他可能的可執行文件將包含含有真實聲明的a.cpp,並進行初始化,並且可以看到b.cpp中的語句作爲前向聲明,只需要在那裏協助編譯器知道我是什麼。

編譯器如何決定哪個文件負責實際的聲明,並因此與我相關的內存分配?如果使用了一個有趣的構造函數,而不是int,那麼這可能會有明顯的影響。

如何回答這個問題的變化,如果有的話,有:

情況2:

a.cpp

extern const int i; 
extern const int i=5; 

b.cpp

extern const int i; 
+0

你聲明它是'extern',你也說你知道它的價值。這似乎是錯誤的。 – tadman

+0

@tadman我編譯時沒有任何錯誤。爲什麼這是錯的?我以爲「extern」只是表示標識符名稱具有外部鏈接。這是否也意味着您無法將其初始化爲已知值? – Jeff

+0

通常'extern'的意思是「存儲在另一個文件中」,鏈接器負責使其同步。你如何編譯所有這些? – tadman

回答

2

初始化程序的存在會立即將聲明變爲定義(除少數例外,在我們的情況下不相關)。這意味着

extern const int i = 5; 

是你i定義。它定義了i併爲其提供了外部鏈接,即創建了實際的i並使其對其他翻譯單元可見(「導出」它)。

同時,

extern const int i; 

是一個非限定聲明如果i。它基本上說i在其他地方定義(「進口」它)。

當你因爲某些原因需要在C++中的全局const對象的extern適當明確的應用變得至關重要,因爲在C++ const對象都默認內部鏈接

請記住,爲使const int對象符合整型常量表達式(ICE)的條件,必須可見ICE初始化程序對該const int對象的聲明。

+0

當情況2中兩個文件都有一個extern const int語句,並且兩個文件都沒有附加到a.cpp中發生的初始化時,會發生什麼? – Jeff

+0

@Jeff:沒什麼特別的。你有'i'的多個非定義聲明(這是非常好的,你可以有無限數量的)和'i'的單個定義(你可以不超過一個)。所以,everythig是爲了。鏈接器將正確地將所有內容鏈接在一起。 – AnT

+0

聽起來好像你說的情況2,「extern const int i = 5;」正在定義。但是我感到困惑的是情況2中的3個語句中的哪一個負責爲我分配內存。即我什麼時候第一次成立?另一個問這個問題的方法是,在這兩個extern const int i中; a.cpp和b.cpp中的語句,一個是真正的聲明,另一個是編譯器對我代表的數據類型的提示。哪個是哪個?謝謝! – Jeff