6
int main()
{
    thread_local int n;
}

The code above is legal in C++11.

According to cppreference:

The thread_local keyword is only allowed for objects declared at namespace scope, objects declared at block scope, and static data members.

I just wonder:

A local variable is always on the current thread's stack, so it's always thread-local. thread_local int n; is completely identical to int n; in such contexts.

Why does C++11 allow to declare a local variable as thread_local, rather than explicitly disable it to avoid abuse?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
xmllmx
  • 39,765
  • 26
  • 162
  • 323
  • 1
    Being local doesn't imply automatic storage duration. In fact, `thread_local` defines a new storage duration for it, just like `static`. – chris Feb 09 '17 at 07:07
  • "Being local doesn't imply automatic storage duration.", Any example? – xmllmx Feb 09 '17 at 07:08
  • 1
    `void foo() { static int s; }` - `s` is not destroyed until the end of the program, assuming `foo` is called so that `s` is created. It is not put on a function's stack frame - that would destroy it too early. `thread_local` is an alternative storage duration to `static` or the **implicit** automatic duration. Just because it's the implicit one doesn't mean it's always that one - you can be explicit and change it, for example, to thread-local. I'm using `static` because it's likely to be more familiar. You can mostly think of `thread_local` the same way, but per thread instead of global. – chris Feb 09 '17 at 07:11

2 Answers2

6

According to the standard, a thread_local variable at block scope is also implicitly static. However, not all static variables are thread_local.

So

 int main()
 {
       thread_local int x;
 }

is actually equivalent to

 int main()
 {
       thread_local static int x;
 }

but different from;

 int main()
 {
       int x;    //  auto implied
 }
Peter
  • 35,646
  • 4
  • 32
  • 74
2

You are correct in that stack variables are thread local.

The thread_local keywork is intended to apply only to variables of global or static scope. Normally a single instance of these variables are created at program (or dll/so) load time. thread_local makes separate instances of these global variables for each thread.

The probable reason for not being the default is that this is new behavior not present in C++03. Also, depending on ABI, a kernel call may be needed to access a thread_local variable which is slow, so only done when really needed.

doron
  • 27,972
  • 12
  • 65
  • 103
  • 3
    "Stack variables" have automatic storage duration. A `thread_local` object can't be on the stack, as its lifetime lasts until the thread terminates. It's more of a thread-specific static object. – molbdnilo Feb 09 '17 at 07:37
  • Which automatically results in different instances for different threads. – doron Feb 09 '17 at 07:43
  • 1
    `thread_local` isn't only about there being separate instances, but also about the lifetime of the object. "A variable with thread storage duration shall be initialized before its first odr-use and, if constructed, shall be destroyed on thread exit." (§ 3.7.2); "When `thread_local` is applied to a variable of block scope the *storage-class-specifier* `static` is implied if it does not appear explicitly." (§ 7.1.1) – molbdnilo Feb 09 '17 at 08:13