Lorsqu'un membre statique dans une classe C++ est à la fois thread_local
et un membre de modèle, il n'est pas initialisé.
#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)
}
Le unordered_map n'est pas initialisé et a un seau comte de zéro. Cela conduit à une division par zéro lorsque la valeur de hachage est pris modulo le comte de seau. Sans l' thread_local
ou sans l' template
il fonctionne très bien. Initialisation du membre manuellement dans chaque thread qui l'utilise (en commentaire de la ligne) résout le problème.
Est-ce un comportement indéterminé selon la norme C++ ou est-ce un bug du compilateur? J'ai essayé avec gcc 7.1.1 et avec 5.2.0, qui produisent de l'erreur. clang 3.8 semble fonctionner.
Edit: je confirme ce comportement avec gcc 8.0.0 20170817 à partir de SVN et a soumis un rapport de bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81880