简体   繁体   中英

When is a `thread_local` global variable initialized?

Consider the following example (lock guards on cout omitted for simplicity).

#include <future>
#include <iostream>
#include <thread>

using namespace std;

struct C
{
  C() { cout << "C constructor\n";}
  ~C() { cout << "C destructor\n";}
};

thread_local C foo;

int main()
{
   int select;
   cin >> select;
   future<void> f[10];
   for ( int i = 0;i < 10; ++i)
       f[i] = async( launch::async,[&](){ if (select) foo; } );
   return 0;
}

On both clang and gcc, this program outputs nothing if the user writes '0', while it prints Constructor / Destructor 10 times if the user inputs a non zero number. Additionally clang complains about an obvious non used expression result.

Since a thread_local storage life-time is supposed to span the entire thread's life, I expected the foo variable to be initialized in every thread regardless of the user input.

I might want to have a thread-local variable for the sole purpose of having a side-effect in the constructor, does the standard mandates that a thread_local object is initialized on its first use?

The standard allows for this behavior, although it doesn't guarantee it. From 3.7.2/2 [basic.stc.thread]:

A variable with thread storage duration shall be initialized before its first odr-use (3.2) and, if constructed, shall be destroyed on thread exit.

It's also possible that the objects are constructed at some other time (eg on program startup), as "before first use" means "at any point as long as it is before" rather than does "just before".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM