Generally it is said that the destructors of static objects are called in the reverse order of the constructors. As I understand, constinit objects are initialized at compile time, so their destructors should be called after the destructors of "normal" static objects.
The program
struct A
{
constexpr A(const char* t): t_(t) {}
~A() {std::cout << "~A(" << t_ << ")\n";}
const char* t_;
};
static A a1("static");
int main () {
static constinit A a2("constinit");
return 0;
}
(using GCC 10), however, gives the output
~A(constinit)
~A(static)
i.e. the constinit object is destroyed before the "normal" static object (although it was constructed earlier). Is the "reverse order" rule no longer valid for constinit objects?
Both a1
and a2
are constant-initialized. The constinit
specifier only asserts that the variable being defined is constant-initialized. So here a1
is initialized before a2
so a2
is destroyed before a1
as expected.
Is the "reverse order" rule no longer valid for constinit
objects? The reverse order rule does not between constant initialized object and dynamicaly initialized object: even if construction of constant initialized object happens before construction of dynamicaly initialized object, destruction of constant initialized object is sequenced as if they had been dynamicaly initialized: [basic.start.term]/3
If an object is initialized statically, the object is destroyed in the same order as if the object was dynamically initialized.