【问题标题】:thread_local static member template definition: initialisation fails with gccthread_local 静态成员模板定义:gcc 初始化失败
【发布时间】:2018-01-24 23:08:26
【问题描述】:

当 C++ 类中的静态成员既是 thread_local 又是成员模板时,它不会被初始化。

#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 它工作正常。在每个使用它的线程中手动初始化成员(注释行)可以解决问题。

这是根据 C++ 标准的未定义行为还是编译器错误?我尝试使用 gcc 7.1.1 和 5.2.0 都产生错误。 clang 3.8 似乎可以工作。

编辑:我使用来自 SVN 的 gcc 8.0.0 20170817 确认了此行为并提交了错误报告:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81880

【问题讨论】:

  • 对我来说似乎是一个明显的错误。你提交错误报告了吗?如果有,可以分享一下链接吗?
  • gcc (HEAD) 8... 也受此影响
  • 我不认为这是一个错误。为什么您的应用程序会浪费时间为您创建的每个线程初始化数据,即使它不会使用它?线程本地存储由操作系统处理,而不是编译器。
  • @Michaël Roy 它是值初始化的(A::m{}; 行)。这里的问题是 gcc 如何处理作为静态成员的模板变量的实例化,它在没有值初始化的情况下发生。
  • gcc 可以很好地处理模板静态变量的“常规”实例化。但是any线程局部变量需要线程局部初始化,因为操作系统需要使用该变量的实际线程为其分配一个槽,

标签: c++ multithreading c++14


【解决方案1】:

再次关闭问题:我提交了一个错误报告,请参阅https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81880

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-02
    • 2016-03-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多