struct foo{
int bar1 = 5;
const static int bar2 = 6;
};
在多個翻譯單元之間共享foo一個頭檔案不會導致和的鏈接錯誤bar1,bar2這是為什么呢?
據我所知,在創建bar1實體之前甚至不存在,foo并且每個實體都bar1將具有唯一的符號,因此不會發生鏈接錯誤。bar2甚至不是一個定義,它是一個帶有初始化程式的宣告,并且const int foo::bar2;只需要在一個檔案中進行初始化,因此不會發生鏈接錯誤。
參考這個答案:https ://stackoverflow.com/a/11301299
我的理解正確嗎?
uj5u.com熱心網友回復:
違反單一定義規則 不需要診斷或編譯器錯誤。
假設bar2在某些翻譯單元中參考了它:某些編譯器可能會成功編譯并鏈接結果代碼。其他編譯器可能不會并拒絕它(大概在鏈接階段)。C 標準表明這是格式錯誤的,但正式的編譯器診斷不是強制性的。這正是 C 標準所說的。
一些編譯器可能會讓這種滑行的原因是因為它們會將所有對靜態類成員的參考行內,因此不會有任何未決議的參考在鏈接階段產生失敗。
uj5u.com熱心網友回復:
只要foo::bar2不是odr-used,程式就沒有問題。您甚至可以foo::bar2以非 odr-uses 的方式使用,它會很好。例如:
std::cout << foo::bar2 1; // prints 7
這是因為foo::bar2在這個運算式中可以簡單地用它的編譯時常量值替換6。它不需要有地址,因此它的定義不需要存在。
一旦您在foo::bar2沒有提供定義的情況下使用 odr-use,程式就會變得格式錯誤,不需要診斷。通常,這會導致鏈接錯誤。例如,您可以在如下代碼中看到它:
std::vector<int> v;
v.push_back(foo::bar2);
這是一個 odr-use offoo::bar2因為push_back通過參考獲取它的引數,需要它的地址存在。foo::bar2除非在某處提供了 的離線定義,否則該程式可能不會構建。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/412628.html
標籤:
上一篇:嵌套預期呼叫時,gtestEXPECT_CALL不起作用
下一篇:特定模板(非型別)的模板函式特化
