Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

thread_local static member template definition: initialisation fails with gcc

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

like image 577
maiphi Avatar asked Aug 16 '17 17:08

maiphi


1 Answers

Once again, to close the question: I submitted a bug report, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81880

like image 175
maiphi Avatar answered Nov 08 '22 03:11

maiphi