8

The following code should be creating the in-class thread_local only once, but it ends up initializing it on every access

#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)

Interestingly the bug only shows when Struct is in an anonymous namespace.

Does someone know if this is a clang bug (gcc does it right - https://wandbox.org/permlink/hsxRj8OdYbt4Eeck) or an inherently incorrect usage of thread_local? If the latter, what is the correct usage? If the former, what exactly is the bug? And is this documented somewhere? Should we open a bug report?

Curious
  • 20,870
  • 8
  • 61
  • 146
  • 3
    You can always open a bug report if something seems like a bug, they'll close it if it isn't – M.M Sep 23 '18 at 23:58
  • @M.M Could you point me to the link where I can go to open one? – Curious Sep 24 '18 at 00:04
  • @SamVarshavchik thanks, there are some ambiguous links there, and I would prefer to go to the right one. For example, I am not sure if this is an LLVM bug or something bigger under the clang umbrella, or even if there is a difference in the two when it comes to this stuff. – Curious Sep 24 '18 at 00:07
  • Going to https://clang.llvm.org/ you will see the a prominent "Bug Reports" in the left hand column, which goes to the same Bugzilla link you get from Google. You should have more trust in Google. It's more often right, than wrong. – Sam Varshavchik Sep 24 '18 at 00:22
  • 1
    duplicate of https://stackoverflow.com/questions/47226542/c-why-static-thread-local-object-constructed-twice – NoSenseEtAl Sep 24 '18 at 08:24
  • @NoSenseEtAl not really, clang interprets that code correctly. With this specific example, the misinterpretation comes from the anonymous namespace and linking I assume – Curious Sep 24 '18 at 19:30
  • Curious: See edit to my answer. This has now been fixed. – einpoklum Jun 05 '19 at 07:35

1 Answers1

1

When you find that a compiler causes runtime behavior which you are relatively certain is incorrect; and another popular compiler does not cause that same behavior - that is sufficient, IMHO, in order to file a bug against said compiler.

As @SamVarshavchik suggestions, you:

  1. Visit LLVM's bug tracker
  2. Create an account if you don't have one
  3. Look for duplicates (e.g. using the term "thread-local")
  4. If you don't find one - you file a bug

I've done just that, so now we have bug 42111.

At worst - it'll be marked as a dupe.

edit: It was not a dupe, and has just now (June 5th 2019) been fixed.

einpoklum
  • 118,144
  • 57
  • 340
  • 684