How to declare a variable as thread local portably?

c, c11, gcc, portability, thread-local-storage

Solution

Combining information from Wikipedia with this list of compiler macros, I came up with the following (untested) version:

#ifndef thread_local
# if __STDC_VERSION__ >= 201112 && !defined __STDC_NO_THREADS__
#  define thread_local _Thread_local
# elif defined _WIN32 && ( \
       defined _MSC_VER || \
       defined __ICL || \
       defined __DMC__ || \
       defined __BORLANDC__ )
#  define thread_local __declspec(thread) 
/* note that ICC (linux) and Clang are covered by __GNUC__ */
# elif defined __GNUC__ || \
       defined __SUNPRO_C || \
       defined __xlC__
#  define thread_local __thread
# else
#  error "Cannot define thread_local"
# endif
#endif

Problem

C11 introduces the `_Thread_local` storage class specifier that can be used in combination with the `static` and `extern` storage class specifiers to declare a variable as thread local. The GNU C compiler suite implements a storage class specifier `__thread` with the same same semantics. Unfortunately I did not find any compiler (I tried gcc, clang and SUN studio) that actually implements the `_Thread_local` keywords. I currently use the following construct to declare a keyword `thread_local`: ``` /* gcc doesn't know _Thread_local from C11 yet */ #ifdef __GNUC__ # define thread_local __thread #elif __STDC_VERSION__ >= 201112L # define thread_local _Thread_local #else # error Don't know how to define thread_local #endif ``` I know that this probably does not work with MSVC and other compilers. Can anybody suggest me a better method to declare `thread_local` in a way that it works in as many compilers as possible? Edit Christoph suggested that Microsoft Visual C allows `__declspec(thread)`. This is the updated macro definition: ``` /* gcc doesn't know _Thread_local from C11 yet */ #ifdef __GNUC__ # define thread_local __thread #elif __STDC_VERSION__ >= 201112L # define thread_local _Thread_local #elif defined(_MSC_VER) # define thread_local __declspec(thread) #else # error Cannot define thread_local #endif ```

Original source