Date: Fri, 11 Feb 2022 20:45:42 +0100
I think i was very missguided in today's call
Let me think if I can clarify the different scenario
for a thread_local of type S
- If S is incomplete the program is ill-formed
- If S has an incomplete destructor or constructor, or if S has a
user-defined constructor or destructor, S is not trivial. In that case,
thread_local in c++ will generate code to initialize and destroy the
thread_local, but that will not happen if the variable is first accessed by
a C TU
So my idea of an attribute to apply to the type is not helping (we don't
care about incomplete types because that's ill-formed).
Another idea, brought up by Tom, was the idea of some syntax at point of
use:
extern "C" thread_local S foo;
But the compiler still needs to create code for initialization and
destruction. I guess in that case, the compiler can eagerly run the
initialization, and that solves the not-yet-initialized problem C faces.
So Tom's solution is actually workable, and mine was just nonsense :)
But I think there is something else to think about here
void f() {
static thread_local S foo;
c_function(&foo); //#1
}
My understanding is that #1 is the issue here. Do we agree with that?
If that is the case, then I think we might have perfect information here
Indeed, c_function here is an extern "C" function (Are there cases where it
isn't?).
A compiler could diagnose a call to c_function with a non-trivial
thread_local object before initialization. I think. Has that been
considered?
I understand this shifts the burden as a matter of QOI, unless we want to
mandate it,
but it avoids burdening both languages and users with extra syntax
complexity.
I might miss some important bits of informations so please do not take this
as more than an unfiltered stream of consciousness
I think the proposal of no_destroy is generally useful yet orthogonal to C
compat concerns.
Thanks,
Corentin
Let me think if I can clarify the different scenario
for a thread_local of type S
- If S is incomplete the program is ill-formed
- If S has an incomplete destructor or constructor, or if S has a
user-defined constructor or destructor, S is not trivial. In that case,
thread_local in c++ will generate code to initialize and destroy the
thread_local, but that will not happen if the variable is first accessed by
a C TU
So my idea of an attribute to apply to the type is not helping (we don't
care about incomplete types because that's ill-formed).
Another idea, brought up by Tom, was the idea of some syntax at point of
use:
extern "C" thread_local S foo;
But the compiler still needs to create code for initialization and
destruction. I guess in that case, the compiler can eagerly run the
initialization, and that solves the not-yet-initialized problem C faces.
So Tom's solution is actually workable, and mine was just nonsense :)
But I think there is something else to think about here
void f() {
static thread_local S foo;
c_function(&foo); //#1
}
My understanding is that #1 is the issue here. Do we agree with that?
If that is the case, then I think we might have perfect information here
Indeed, c_function here is an extern "C" function (Are there cases where it
isn't?).
A compiler could diagnose a call to c_function with a non-trivial
thread_local object before initialization. I think. Has that been
considered?
I understand this shifts the burden as a matter of QOI, unless we want to
mandate it,
but it avoids burdening both languages and users with extra syntax
complexity.
I might miss some important bits of informations so please do not take this
as more than an unfiltered stream of consciousness
I think the proposal of no_destroy is generally useful yet orthogonal to C
compat concerns.
Thanks,
Corentin
Received on 2022-02-11 19:45:54