将静态参数clang到std :: fill导致链接器失败

时间:2017-04-03 22:25:59

标签: c++ static linker linker-errors clang++

使用Clang ++(v3.8.0),由于sSomeValue是未定义的引用,以下代码无法链接。

#include <iostream>

struct MyClass
{
    static constexpr int sSomeSize = 3;
    static constexpr int sSomeValue = 10;
};

int foo()
{
    int someArray[MyClass::sSomeSize] = {};
    std::fill(std::begin(someArray), std::end(someArray), MyClass::sSomeValue);
    return someArray[0];
}

int main()
{
    std::cout << foo() << std::endl;
}

更确切地说:

clang++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out

/tmp/main-c8de0c.o: In function `foo()':
main.cpp:(.text+0x2): undefined reference to `MyClass::sSomeValue'
/tmp/main-c8de0c.o: In function `main':
main.cpp:(.text+0x16): undefined reference to `MyClass::sSomeValue'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

但是,将foo的定义更改为

int foo()
{
    int someArray[MyClass::sSomeSize] = {MyClass::sSomeValue, MyClass::sSomeValue, MyClass::sSomeValue};
    return someArray[0];
}

未显示相同的链接器错误,即使仍在使用sSomeValue

这里发生了什么?编译器是否围绕std::fill调用进行了一些我可能不知道的优化? 请注意,g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out按照v6.3.0的预期编译,链接和输出10

1 个答案:

答案 0 :(得分:1)

该错误与std :: fill无关。

如果您参考下面的文档,它会说:引用变量可以声明为constexpr(它们的初始值设定项必须是引用常量表达式):

http://en.cppreference.com/w/cpp/language/constexpr

对代码进行轻微修改可以正常工作。只需制作结构变量&#34; const&amp;&#34;如上所述。

#include <iostream>

struct MyClass
{
    static constexpr int const& sSomeSize = 3;
    static constexpr int const& sSomeValue = 10;
};

int foo()
{
    int someArray[MyClass::sSomeSize] = {};
    std::fill(std::begin(someArray), std::end(someArray), MyClass::sSomeValue);
    return someArray[0];
}

int main()
{
    std::cout << foo() << std::endl;
}

另请参阅此处有关constexprstatic的详细解释文章 &#34; Does static constexpr variable make sense?

特别是勾选答案的最后一段。