You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
structA {
A() {
a = 1;
}
int a;
};
structB {
B() : _a(_ca) {}
A _a;
staticinline A _ca;
};
B b;
intmain() {
return b._a.a;
}
Currently it returns 0 with -O2 using clang: https://gcc.godbolt.org/z/66hGqoaj8
and returns 1 with -O0. Compiled by all the other compilers, it results in 1 as well.
It seems initialization of static inline A _ca should be done earlier than initialization of B.
According to [basic.start.dynamic]: if V has partially-ordered initialization, W does not have unordered initialization, and for every definition E of W there exists a definition D of V such that D is appearance-ordered before E ... V is sequenced before the initialization of W;
Let's say static inline A _ca is definition of V, B b is definition of W, seems by appearance order _ca should have been initialized before b, however with optimization a=1 initialization fails to happen before initializing B b apparently. Please correct me if my interpretation of the standard is wrong in this case.
The text was updated successfully, but these errors were encountered:
Another interesting aspect of this issue, coming from how it was discovered originally. Initialization order may be affected by adding irrelevant global constants to original example.
Basically it comes to the following:
Adding const std::string global constant on top makes initialization work expectedly in clang trunk but only with C++17. Link to godbolt
On clang 17, it seems to behave expectedly with both C++17 and 20 after the same addition. Link to godbolt
Might not be that relevant since it might be just optimization noise, but makes it more surprising when encountering this in the wild.
Adding any other struct member or increasing data size adds runtime initialization of _ca and returned value is correct:
struct A {
A() {
a = 1;
}
int a;
int b; // fixes issues
};
struct B {
B() : _a(_ca) {}
A _a;
static inline A _ca;
};
B b;
int main() {
return b._a.a;
}```
Please take a look at the following example:
Currently it returns 0 with
-O2
using clang:https://gcc.godbolt.org/z/66hGqoaj8
and returns 1 with
-O0
. Compiled by all the other compilers, it results in 1 as well.It seems initialization of
static inline A _ca
should be done earlier than initialization ofB
.According to
[basic.start.dynamic]
:if V has partially-ordered initialization, W does not have unordered initialization, and for every definition E of W there exists a definition D of V such that D is appearance-ordered before E ... V is sequenced before the initialization of W;
Let's say
static inline A _ca
is definition ofV
,B b
is definition ofW
, seems by appearance order_ca
should have been initialized beforeb
, however with optimizationa=1
initialization fails to happen before initializingB b
apparently. Please correct me if my interpretation of the standard is wrong in this case.The text was updated successfully, but these errors were encountered: