模板中的thread_local可能存在clang编译错误

Pet*_*mps 5 c++ macos multithreading clang++ c++14

在我的项目中,我需要为数据成员的每个实例单独的线程本地存储.因为我在实现此功能时遇到了问题,所以我将代码的简化版本提取到以下C++ 14程序中:

#include <iostream>
#include <unordered_map>
#include <vector>

template<class T> class ThreadLocalMember
{
public:
    T& local() { return store.map[this]; }
private:
    struct Store
    {
        Store() { std::cout << "construct" << std::endl; }
        ~Store() { std::cout << "destruct" << std::endl; }
        std::unordered_map<ThreadLocalMember<T>*, T> map;
    };
    static thread_local Store store;
};

template <class T> thread_local typename ThreadLocalMember<T>::Store ThreadLocalMember<T>::store;

int main()
{
    ThreadLocalMember<int> counter;
    std::cout << "point 1" << std::endl;
    int result = counter.local();
    std::cout << "point 2; result: " << result << std::endl;
    return result;
}
Run Code Online (Sandbox Code Playgroud)

预期的产出是

point 1
construct
point 2; result: 0
destruct
Run Code Online (Sandbox Code Playgroud)

但是,在MacOS High Sierra 10.13.4上使用clang Apple LLVM版本9.1.0(clang-902.0.39.1)进行编译时使用

clang++ -std=c++14 -O3 ThreadLocalMember.cpp -o test
Run Code Online (Sandbox Code Playgroud)

(或带-O1-O2)输出是:

point 1
Illegal instruction: 4
Run Code Online (Sandbox Code Playgroud)

似乎从不执行thread_local变量的构造函数,并且在首次访问变量时程序崩溃.

问题消失了

  • 程序是在没有优化的情况下编译的(在生产模式下是不可接受的)
  • 模板类被常规类替换(可能的解决方法,但非常烦人)
  • thread_local关键字在两个地方被删除(但是当有多个线程时,程序不再执行我需要它做的事情)

在Ubuntu 16上使用gcc 5.4.0时,程序也会编译并运行正常,有或没有优化标志.

我的代码有问题,或者我正在查看clang编译器错误?