2014-01-11 17 views
1

I所定義有這種情況:類使用全局的extern const的變量,其具有內部鏈接

// Test.h 
extern const int param; 
class Test 
{ 
private: 
    int i; 
public: 
    int foo(); 
}; 

// Test.cpp 
#include "Test.h" 
int Test::foo() { return param*10; } 

// core.h 
#include "Test.h" 
const int param = 1; // should have internal linkage later in core.cpp 
int do_stuff(); 

// core.cpp 
#include "core.h" 
int do_stuff() { Test obj; return obj.foo(); } 
int main() { return do_stuff(); } 

但是沒有鏈接器錯誤。鏈接器如何查看Test.cpp的const int param,它是通過core.cpp中定義的core.h具有內部鏈接(默認爲const定義)?

當我重寫core.h這樣的(改變兩行):

// core.h 
const int param = 1; 
#include "Test.h" 
int do_stuff(); 

總會有一個鏈接錯誤失蹤param。然後,當我改變它是這樣的:

// core.h 
extern const int param = 1; 
#include "Test.h" 
int do_stuff(); 

所有的作品再次。

我想,也許在原來的情況下,在core.cpp裏面有一個類Test的自動內聯,所以Test.cpp不存在,整個代碼都在core.cpp中,這樣一切正常。但爲什麼它應該依賴於改變core.h中的兩行?

回答

0

你對const定義的內部鏈接的假設並不總是如此。請參見標準部分3.5 Program linkage,第12頁。 3(我引用N3690):

具有名稱命名空間範圍(3.3.6)具有如果是

  • 變量,函數或函數模板名稱內部連接這是明確宣佈爲靜態的;或者,

  • 被顯式聲明const或constexpr和既沒有明確聲明爲extern也不非易失性可變先前聲明爲具有外部連接;或

  • 匿名聯盟的數據成員。

所以對於第一種情況param有外部鏈接,且一切正常。

對於第二種情況,core.cpp中有一個內部鏈接的param,但還有另一個聲明的param具有外部鏈接但沒有定義。

在第三種情況下,再次有一個param

+0

感謝您的完美答案! – mb84