2016-07-14 55 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'才意味着内联:-) –

相关问题