2017-08-16 11 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 के बिना यह ठीक काम करता है। प्रत्येक धागे में मैन्युअल रूप से सदस्य को प्रारंभ करना (टिप्पणी पंक्ति) समस्या हल करती है।

क्या यह अनिर्धारित व्यवहार सी ++ मानक के अनुसार है या यह एक कंपाइलर बग हो सकता है? मैंने जीसीसी 7.1.1 और 5.2.0 के साथ कोशिश की जो दोनों त्रुटि उत्पन्न करते हैं। clang 3.8 काम करने लगता है।

संपादित करें: मैं SVN से जीसीसी 8.0.0 20,170,817 के साथ इस व्यवहार की पुष्टि की और एक बग रिपोर्ट प्रस्तुत: एक बार फिर https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81880

+3

की तरह लगता है मेरे लिए एक स्पष्ट बग। क्या आपने एक बग्रेपोर्ट सबमिट किया था? यदि आपने किया, तो क्या आप लिंक साझा कर सकते हैं? – SergeyA

+0

जीसीसी (HEAD) 8 ... इससे भी प्रभावित होता है – Swift

+1

मुझे नहीं लगता कि यह एक बग है। आपके ऐप को आपके द्वारा बनाए गए प्रत्येक थ्रेड के लिए डेटा प्रारंभ करने का समय बर्बाद क्यों करेगा, भले ही वह इसका उपयोग न करे? थ्रेड-स्थानीय भंडारण ओएस द्वारा संभाला जाता है, न कि संकलक द्वारा। –

उत्तर

संबंधित मुद्दे