When a static member in a C++ class is both thread_local
and a member template, it doesn't get initialised.
#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)
}
The unordered_map is not initialised and has a bucket count of zero. This leads to a zero division when the hash is taken modulo the bucket count. Without the thread_local
or without the template
it works fine. Initialising the member manually in every thread which uses it (commented line) solves the problem.
Is this undefined behaviour according to the C++ standard or could this be a compiler bug? I tried with gcc 7.1.1 and with 5.2.0 which both produce the error. clang 3.8 seems to work.
Edit: I confirmed this behaviour with gcc 8.0.0 20170817 from SVN and submitted a bug report: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81880
Once again, to close the question: I submitted a bug report, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81880
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With