C++ 模板中线程为本地时可能出现的编译器错误

C++ 模板中线程为本地时可能出现的编译器错误,c++,multithreading,macos,c++14,clang++,C++,Multithreading,Macos,C++14,Clang++,在我的项目中,我需要为数据成员的每个实例提供单独的线程本地存储。由于在实现此功能时遇到问题,我将代码的简化版本提取到以下C++14程序中: #include <iostream> #include <unordered_map> #include <vector> template<class T> class ThreadLocalMember { public: T& local() { return store.map[th

在我的项目中,我需要为数据成员的每个实例提供单独的线程本地存储。由于在实现此功能时遇到问题,我将代码的简化版本提取到以下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;
}
但是,当在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
(或使用
-O1
-O2
)输出为:

point 1
Illegal instruction: 4
似乎从未执行thread_局部变量的构造函数,并且在首次访问该变量时程序崩溃

当你离开时,问题就消失了

  • 该程序未经优化(在生产模式下不可接受)
  • 模板类被一个常规类替换(一个可能的解决方法,但非常烦人)
  • thread_local关键字在两个位置都被删除(但是当有多个线程时,程序不再执行我需要它执行的操作)
在Ubuntu16上使用GCC5.4.0时,无论是否带有优化标志,该程序都可以编译并运行良好


我的代码有什么问题吗,或者我看到的是一个铿锵编译器错误?

您的程序使用最新的实验性铿锵7.01运行良好。程序是否与
-O2
一起工作?2.如果“从对象到数据的每个线程映射”不起作用,作为一种解决方法,您可以在每个对象中使用“从线程到数据的每个对象映射”:
std::map
。@Angew项目1:优化级别
-O1
-O2
也会中断程序(发出叮当声)。第二项:谢谢你的提示;但是,此解决方案需要在每次访问时锁定映射,除非您可以为所有线程预填充它(我无法)。有关
-O1
-O2
的信息非常相关,您可能希望将其包含在内。这是因为众所周知,
-O3
偶尔会产生错误的代码。
point 1
Illegal instruction: 4