链接器错误与静态常量似乎没有使用odr

时间:2015-07-17 22:33:07

标签: c++ c++14 one-definition-rule

当你进入细节时,标准中使用odr-used的定义相当令人困惑(至少,对我而言)。我通常依赖于“如果引用”的非正式定义,除了,当左值到右值转换可用时。对于积分常数,它们应被视为rvalues,这似乎应该从参考规则中排除。这是我的示例代码无法链接:

class Test
{
public:
    Test();
    static constexpr int MIN_VALUE { 5 };
    int m_otherValue = 10;
};

Test::Test()
{
    m_otherValue = std::max(m_otherValue, MIN_VALUE);
}

int main()
{
    Test t;
}

我得到的链接器错误:

clang++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
/tmp/main-e2122e.o: In function `Test::Test()':
main.cpp:(.text+0x2): undefined reference to `Test::MIN_VALUE'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

实时样本:http://coliru.stacked-crooked.com/a/4d4c27d6b7683fe8

为什么需要定义MIN_VALUE?它只是文字值的常量,编译器应该将其优化为std::max(m_otherValue, 5)。所以我只是不明白。

2 个答案:

答案 0 :(得分:7)

std::max通过引用而非值来获取其参数。不允许执行左值到右值转换,然后从该右值构造临时对象。 std::max 可以检查两个参数是否是对同一个对象的引用,对于所有编译器都知道,如果调用{true,则需要进行检查std::max(MIN_VALUE, MIN_VALUE) {1}}。

答案 1 :(得分:1)

如果您阅读了std::max的参考文献,您会看到它通过参考进行参数,并根据this odr-used reference

  

非正式地说,如果......引用被绑定,那么对象就会被使用...

由于您将MIN_VALUE传递给了一个带引用的函数,因此该成员 odr-used 并需要一个单独的定义。