Created on 2022-03-01.00:00:00 last changed 2 months ago
Subclause 9.2.7 [dcl.constinit] paragraph 2 states:
If a variable declared with the constinit specifier has dynamic initialization (22.214.171.124 [basic.start.dynamic]), the program is ill-formed. [ Note: The constinit specifier ensures that the variable is initialized during static initialization (126.96.36.199 [basic.start.static]). —end note]
Subclause 188.8.131.52 [basic.start.static] paragraph 3 gives permission for an implementation to perform static initialization in lieu of dynamic initialization:
An implementation is permitted to perform the initialization of a variable with static or thread storage duration as a static initialization even if such initialization is not required to be done statically, provided that ...
constinit will assuredly not give a diagnostic for variables that are constant initialized (7.7 [expr.const] paragraph 2), because those are required to be statically initialized and thus will never be dynamically initialized. Conversely, constinit is guaranteed to give a diagnostic for variables that cannot be statically initialized, for example those with an initializer whose value depends on runtime conditions.
Between those boundaries, it is unclear whether constinit ought to give a diagnostic for variables whose initializer does not satisfy the constraints of constant-initialized, yet the implementation takes advantage of the permission to turn dynamic initialization into static initialization. For example,
float f; constinit int * pi = (int*) &f; // reinterpret_cast, not constant-initialized
The current wording seems to imply that constinit accurately reflects whether dynamic initialization was turned into static initialization by the implementation. However, that is impossible to implement, because such decisions are often made by the optimizer, which runs later than the compiler front-end interpreting the program text containing constinit.
There is value in permitting constinit not to diagnose some of the dynamic initializations that are turned into static initializations.
There is also value in having portable semantics of constinit.
See also issue 2536.