Open t3nsor opened 3 months ago
The suggested resolution seems too strong. In the case of deferred dynamic initialization, the dynamic initialization should not happen before the initialization of (at least some) thread storage duration variables.
Consider the following example, where whatever()
is something that prevents constant-initialization:
// TU A
int a = whatever();
thread_local int b = whatever();
void foo();
int main() {
foo();
}
// TU B
static int c = whatever();
void foo() { return c; }
My understanding is that initializing a
, then b
, then c
is intended to be permitted in the status quo.
OK, how about this.
Edit [basic.start.static]/1:
Variables with static storage duration are initialized as a consequence of program initiation. Variables with thread storage duration are initialized as a consequence of thread execution. All non-deferred ([basic.start.dynamic]) initialization (if any) of non-block variables with static storage duration strongly happens before any non-deferred initialization of non-block variables with thread storage duration. Within each of these phases of initiation, initialization occurs as follows.
Edit [basic.start.dynamic]/5:
It is implementation-defined whether the dynamic initialization of a non-block non-inline variable o with static storage duration is sequenced before the first statement of main or is deferred. If it is deferred, it strongly happens before any non-initialization odr-use of any non-inline function or non-inline variable defined in the same translation unit as ~the variable to be initialized~ o and any deferred initialization of non-inline non-block variables with thread storage duration defined in the same translation unit as o.39 It is implementation-defined in which threads and at which points in the program such deferred dynamic initialization occurs.
Interestingly, static initialization is arguably "non-deferred", so the first paragraph would make static initialization of variables with static storage duration happen before static initialization of variables with thread storage duration. I don't think that's a problem, though?
The second paragraph doesn't appear to ensure that deferred dynamic initialization of variables with thread storage duration happens before an odr-use of a function or variable in the same TU, but I think that's also a problem with the status quo.
Otherwise, I think this looks fine?
so the first paragraph would make static initialization of variables with static storage duration happen before static initialization of variables with thread storage duration. I don't think that's a problem, though?
That might be what the status quo is trying to say anyway with its "within each of these phases" wording.
The second paragraph doesn't appear to ensure that deferred dynamic initialization of variables with thread storage duration happens before an odr-use of a function or variable in the same TU
Deferred dynamic initialization of thread local variables is governed by p7. In p5, it's true that adding the suggested guarantee would possibly allow a function in the same TU to observe a thread local variable prior to its dynamic initialization. However, such a use of that function would not be a "non-initialization odr-use" because it would be caused by the initialization of a static variable, so it wouldn't violate p7.
Ah, yes, sorry. I missed that paragraph. Looks fine then.
CWG2914
Full name of submitter: Brian Bi
Issue description: It is heavily implied, but not stated outright, that initialization of all non-local static variables happens before initialization of all non-local thread-local variables. For example, [basic.start.static] seems to refer to initializing variables with static storage duration and thread storage duration as "phases", which may imply that one phase completes before the other starts. [basic.start.term]/2 appears to guarantee that returning from
main
destroys all thread-local variables of the main thread before destroying any static variables, which would be peculiar if the static variables were not initialized first.Suggested resolution: Edit [basic.start.static]/1 as shown: