c++staticlinkagethread-local

Static block variables linkage?


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_localand thread_local static are totally equivalent)


Solution

  • 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