2016-07-14 51 views
5

考慮以下代碼:在哪個編譯單元中存在一個constexpr變量?

struct foo 
{ 
    static constexpr int value = 42; 
}; 

void bar(const int* value) { std::cout << *value; } 
int main() { bar(&foo::value); } 

這將編譯下online compilerscouple我想罰款,沒有警告。鑑於沒有單個.cpp文件定義constexpr值,如果從不同的編譯單元調用bar方法,指針的值可能會不同?或者,標準是否保證該值在所有編譯單元中只分配一次(即隱含的_declspec(selectany))?

+0

你剛剛編譯過,還是鏈接了程序? –

+1

只要您[實際使用](http://ideone.com/Bi5oEt)地址,您需要提供一個定義。 –

+0

該代碼違反了單定義規則,但由於這是未定義的行爲,因此編譯器不需要發出任何警告。 – cpplearner

回答

9

它不適用於我---我得到一個鏈接器錯誤。 http://coliru.stacked-crooked.com/a/59e2cf56122733d0

如果你不ODR,使用靜態constexpr成員,你能想象的任何需要的地方,它的內聯,就不住在任何編譯單元。如果你 odr-使用它,像你在你的程序中所做的那樣,你的必須定義它。

+0

你怎麼定義它?我認爲聲明中需要分配的值可以作爲constexpr使用。你是否在聲明和定義中分配它? – Trillian

+0

@Trillian如果你在聲明中初始化它,那麼你不會在定義中初始化它。 – Brian

+0

是的,但不是constexpr需要初始化定義的聲明和odr初始化? – Trillian

1

通常取一個對象的地址構成一個odr使用,這將需要在某處定義該對象(如果不是,則導致鏈接器錯誤)。但是,如果得到的表達式是丟棄的值,則可以將地址取爲不使用odr。可以肯定,你的使用可以被一些編譯器視爲屬於豁免範圍,因爲它被作爲參數傳遞給立即丟棄它的函數。

4

其他答案是正確的,但情況將在C++ 17中改變,採用inline variables (p0386)。 constexpr將意味着內聯。

+1

要明確的是,只有靜態類數據成員上的'constexpr'才意味着內聯:-) –

相關問題