C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Fix bad thread_local codegen (using an attribute?)

From: Thiago Macieira <thiago_at_[hidden]>
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.

-- 
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