Date: Thu, 22 Jan 2026 22:28:39 -0800
On Thursday, 22 January 2026 19:14:00 Pacific Standard Time Levo D via Std-
Proposals wrote:
> > That forces you to write code that must be initialised at compile time
> > (stored in the .tdata section if not zeroes), but it's not sufficient for
> > the problem. To "solve" this problem of initialisation, all accesses to
> > the variable must see the initialisation. And if the variable is used
> > over multiple TUs, then it needs to be inline.
> >
> > Given most code is PIC, I don't see much value in accessing the variable
> > directly. Make it static in one TU and add an accessor function.
>
> That'd be trading a call to an initialization function with a call to an
> accessor.
No. It trades the call to __tls_get_addr() function with a call to another
function.
https://gcc.godbolt.org/z/PdGfq136E
Now, the called function must call __tls_get_addr() anyway, but my experience
with __thread and thread_local is that compilers are too happy to call it time
and time again (as your paste showed), instead of getting the address once and
keeping it. If you use a local variable and keep it in your function, the
compiler will generate better code.
> I’m surprised there’s no way to say this must be initialized when you create
> a thread, so I can avoid calls at the call site. I’ll stick to my __thread
> workaround
There isn't a way because there's no registration function. Even if there
were, the registration might have come too late: the thread may have started
before the module containing the variable was dlopen()ed.
If a variable doesn't need dynamic initialisation (constexpr constructor and
trivial destructor), then the runtime can "initialise" the variable without
calling the initialiser function. Note that constinit enforces the use of a
constexpr constructor but does not require a trivial destructor. And if what
you want is that the compilers don't have to emit a call to initialise on
demand, then obey the rules: constexpr construction, trivial destruction.
And this is exactly a limitation of __thread. So for what you want to do,
__thread suffices. Keep using it.
Proposals wrote:
> > That forces you to write code that must be initialised at compile time
> > (stored in the .tdata section if not zeroes), but it's not sufficient for
> > the problem. To "solve" this problem of initialisation, all accesses to
> > the variable must see the initialisation. And if the variable is used
> > over multiple TUs, then it needs to be inline.
> >
> > Given most code is PIC, I don't see much value in accessing the variable
> > directly. Make it static in one TU and add an accessor function.
>
> That'd be trading a call to an initialization function with a call to an
> accessor.
No. It trades the call to __tls_get_addr() function with a call to another
function.
https://gcc.godbolt.org/z/PdGfq136E
Now, the called function must call __tls_get_addr() anyway, but my experience
with __thread and thread_local is that compilers are too happy to call it time
and time again (as your paste showed), instead of getting the address once and
keeping it. If you use a local variable and keep it in your function, the
compiler will generate better code.
> I’m surprised there’s no way to say this must be initialized when you create
> a thread, so I can avoid calls at the call site. I’ll stick to my __thread
> workaround
There isn't a way because there's no registration function. Even if there
were, the registration might have come too late: the thread may have started
before the module containing the variable was dlopen()ed.
If a variable doesn't need dynamic initialisation (constexpr constructor and
trivial destructor), then the runtime can "initialise" the variable without
calling the initialiser function. Note that constinit enforces the use of a
constexpr constructor but does not require a trivial destructor. And if what
you want is that the compilers don't have to emit a call to initialise on
demand, then obey the rules: constexpr construction, trivial destruction.
And this is exactly a limitation of __thread. So for what you want to do,
__thread suffices. Keep using it.
-- Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org Principal Engineer - Intel Data Center - Platform & Sys. Eng.
Received on 2026-01-23 06:28:46
