I'm confused by storage class specifiers
What is the linkage of thread_local
and static
variables? My understanding is that they have no linkage (thus they are not seen outside the block) but they are initialized once and their value is kept when control is passing again on their declaration (which is skipped according to cppreference wording).
Am I correct?
(A consequence would be that thread_local
and thread_local static
are totally equivalent)
Static block variables linkage? What is the linkage of thread_local and static variables?
It depends on/at what scope you declare the variable. For example consider the following contrived example.
The rules are given in the page you linked storage class specifier:
The storage class specifiers are a part of the decl-specifier-seq of a name's declaration syntax. Together with the scope of the name, they control two independent properties of the name: its storage duration and its linkage.
Note the emphasis on the "together with scope of the name".
#include <iostream>
//at namespace scope(global)
static int i = 0; //internal linkage
int j = 0; //external linkage
const int k = 0; //internal linkage; static is implied
extern int l = 0; //external linkage
extern const int m = 0; //external linkage
static int n = 0; //internal linkage
extern thread_local int p; //external linkage
//at local/block scope
void func()
{
static int i = 0; //no linkage
int j = 0; //no linkage
const int k = 0; //no linkage
extern int n; //internal linkage in latest c++ draft
thread_local int m = 0; //no linkage
}
int main()
{
}
Note that the n
in extern int n;
in the above example has internal linkage in c++23 as explained here.
Also see Are C++11 thread_local variables automatically static? where the accepted answer explains that
According to c++ standard, when
thread_local
is applied to a variable of block scope the storage-class-specifier static is implied if it does not appear explicitly