2017-08-16 73 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處理,而不是由編譯器處理。 –

回答