32 votes

définition de modèle de membre statique thread_local: l'initialisation échoue avec gcc

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

4voto

maiphi Points 186

Encore une fois, pour clore la question: j’ai soumis un rapport de bogue, voir https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81880

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X