英特尔对GCC的constexpr

时间:2015-02-04 15:09:25

标签: c++ gcc intel static-members constexpr

以下代码与Intel-2015编译正常,但与gcc 4.8.3失败 谁是对的?

#include <iostream>

void f( int const& x ) { std::cout << x << std::endl; }

struct S
{
    static constexpr int ce = 42;
};

int main()
{
    f(S::ce);

    return 0;
}

g ++错误:

/tmp/ccOIxa2V.o: In function `main':
test_constexpr.cpp:(.text+0x36): undefined reference to `S::ce'
collect2: error: ld returned 1 exit status

2 个答案:

答案 0 :(得分:4)

我认为海湾合作委员会是对的。 BTW,CLang 3.5.1给出了同样的错误。

事情是,只有在不采用地址并且它们没有绑定到引用的情况下,才允许不定义常量静态变量。

您的示例绑定了对它的引用,因此需要显式定义。

从C ++ 11草案(9.4.2.3),方便编辑:

  

可以使用constexpr说明符在类定义中声明文字类型的静态数据成员; [...]如果在程序[...]中使用了odr-used(3.2),该成员仍应在命名空间范围内定义。

在3.2:

  

其名称显示为潜在评估表达式的变量[...]除非是满足出现在常量表达式(5.19)和左值到右值转换中的要求的对象,否则使用odr 4.1)立即应用。

粗略地说,每次使用变量时都会执行左值到右值的转换,除非将引用或参数绑定到一元接收地址运算符&

答案 1 :(得分:4)

因为函数f采用引用参数,所以引用可以在运行时指向S::ce的定义;编译器不能只用文字42替换参数。所以你必须添加一个类外定义:

const int S::ce;

就像使用非constexpr变量一样。这会在运行时为值分配一个内存位置,供引用和在编译时无法计算的其他内容使用。

有关详细信息,请参阅this GCC bug report(其中的评论解释了为什么它实际上不是错误)。