2017-08-16 40 views
28

当C++类中的静态成员同时是thread_local和成员模板时,它不会被初始化。thread_local静态成员模板定义:使用gcc初始化失败

#include <unordered_map> 
#include <iostream> 

class A { 
public: 
    template<typename T> 
    thread_local static std::unordered_map<int,T> m; 
}; 

template<typename T> 
thread_local std::unordered_map<int,T> A::m{}; 

int main() { 
    // A::m<int> = std::unordered_map<int,int>{}; // solves the problem 
    std::cout << A::m<int>.bucket_count() << std::endl; // returns zero. 
    A::m<int>.insert({1,2}); // causes SIGPFE (hash modulo bucket_count) 
} 

unordered_map未初始化并且存储区计数为零。当哈希以桶计数为模时,这导致零除法。没有thread_local或没有template它工作正常。在每个使用它的线程中手动初始化成员(注释行)解决了这个问题。

这是根据C++标准的未定义的行为还是这可能是一个编译器错误?我试着用gcc 7.1.1和5.2.0都产生错误。叮当3.8似乎工作。

编辑:我从证实SVN这种行为与GCC 8.0.0 20170817,并提交Bug报告:再次https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81880

+3

好像一个明确的错误给我。您提交了错误报告吗?如果你有,请分享链接? – SergeyA

+0

gcc(HEAD)8 ...也受此影响 – Swift

+1

我不认为这是一个错误。为什么您的应用程序会浪费时间为您创建的每个线程初始化数据,即使它不会使用它?线程本地存储由OS处理,而不是由编译器处理。 –

回答