【问题标题】:Bug in clang thread_local initializationclang thread_local 初始化中的错误
【发布时间】:2019-02-27 11:41:57
【问题描述】:

以下代码应该只创建一次类内thread_local,但最终会在每次访问时对其进行初始化

#include <iostream>
#include <thread>

using std::cout;
using std::endl;

template <typename T>
class Something {
public:
    struct TLBookkeeping {
        TLBookkeeping() {
            std::cout << "TLBookkeeping() " << std::this_thread::get_id() << std::endl;
        }
    };

    static void foo();
    static thread_local TLBookkeeping bookkeeping_;
};

template <typename T>
thread_local typename Something<T>::TLBookkeeping Something<T>::bookkeeping_;

template <typename T>
void Something<T>::foo() {
    std::cout << &bookkeeping_ << std::endl;
    std::cout << &bookkeeping_ << std::endl;
}

namespace {
struct Struct {};
}

int main() {    
    Something<Struct>::foo();
}

(https://wandbox.org/permlink/fgqCDHV0axKDRt89)

有趣的是,该错误仅在 Struct 位于匿名命名空间中时显示。

有人知道这是一个 clang 错误(gcc 做得对 - https://wandbox.org/permlink/hsxRj8OdYbt4Eeck)还是 thread_local 的固有错误用法?如果是后者,正确的用法是什么?如果是前者,究竟是什么错误?这是否记录在某处?我们应该打开错误报告吗?

【问题讨论】:

  • 如果某件事看起来像错误,您可以随时打开错误报告,如果不是,他们会关闭它
  • @M.M 你能指出我可以打开一个链接吗?
  • @SamVarshavchik 谢谢,那里有一些模棱两可的链接,我更愿意找到正确的链接。例如,我不确定这是 LLVM 错误还是铿锵伞下更大的东西,或者即使在这方面两者之间存在差异。
  • 转到clang.llvm.org,您将在左侧栏中看到一个突出的“错误报告”,它指向您从 Google 获得的同一个 Bugzilla 链接。你应该更加信任谷歌。它往往是正确的,而不是错误的。

标签: c++ multithreading clang c++17 thread-local


【解决方案1】:

当您发现编译器导致您相对确定不正确的运行时行为时;并且另一个流行的编译器不会导致相同的行为 - 恕我直言,这足以针对所述编译器提交错误。

按照@SamVarshavchik 的建议,您:

  1. 访问LLVM's bug tracker
  2. 如果您没有帐户,请创建一个帐户
  3. 查找重复项(例如,使用术语“线程本地”)
  4. 如果你没有找到 - 你提交一个错误

我已经做到了,所以现在我们有了bug 42111

在最坏的情况下 - 它会被标记为欺骗。

编辑:这不是骗子,刚刚(2019 年 6 月 5 日)已修复。

【讨论】:

    猜你喜欢
    • 2017-09-11
    • 1970-01-01
    • 1970-01-01
    • 2014-12-20
    • 1970-01-01
    • 1970-01-01
    • 2014-08-06
    • 2018-07-29
    • 2014-03-01
    相关资源
    最近更新 更多