在我的项目中,我需要为数据成员的每个实例提供单独的线程本地存储。因为我在实现此功能时遇到了问题,所以我将代码的简化版本提取到以下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;
}
预期输出
point 1
construct
point 2; result: 0
destruct
但是,使用
在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_local变量的构造函数,并且在首次访问变量时程序崩溃。
时问题就消失了
在Ubuntu 16上使用gcc 5.4.0时,程序也会编译并运行正常,有或没有优化标志。
我的代码有问题,还是我在查看clang编译器错误?