What does the standard have to say about function-local static initialization during program exit?
EDIT: For clarity, I mean a case as in the code example - the local static b
is constructed after another static a
is constructed(so supposedly b
should be destroyed before a
), but b
is also constructed during a
's destructor, so should it be destroyed immediately? after? UB?
I didn't manage to find any reference to this matter.
I'd like to know if such a case is UB, or should it have some defined behaviour?
The following code is an example of that:
struct B{};
void foo()
{
static B b;
}
struct A
{
~A() { foo(); }
};
int main()
{
static A a;
return 0;
}
As you can see, the destructor of A would occur during program exit(since it has static storage), and it'll try to construct a B static instance.
I'm more interested in C++17 if it makes any difference in this subject.
Static variables within function scope are treated the same, the scoping is purely a language level construct. For this reason you are guaranteed that a static variable will be initialized to 0 (unless you specify something else) rather than an undefined value.
Is initialisation mandatory for local static variables? Explanation: None.
static variables are only initialized once when the program is first loaded into memory (not each time that the function is called like automatic or local variables)
The space for the static variable is allocated only one time and this is used for the entirety of the program. Once this variable is declared, it exists till the program executes. So, the lifetime of a static variable is the lifetime of the program.
I do not see a conflict here, given that foo()
is only ever called from the destructor of A
.
From [stmt.dcl]/5 [emphasis mine]:
A block-scope object with static or thread storage duration will be destroyed if and only if it was constructed. [ Note: [basic.start.term] describes the order in which block-scope objects with static and thread storage duration are destroyed. — end note ]
And, from [basic.start.term]/4 [emphasis mine]:
If a function contains a block-scope object of static or thread storage duration that has been destroyed and the function is called during the destruction of an object with static or thread storage duration, the program has undefined behavior if the flow of control passes through the definition of the previously destroyed block-scope object. Likewise, the behavior is undefined if the block-scope object is used indirectly (i.e., through a pointer) after its destruction.
As b
in foo()
is (in this particular example) not constructed until the destruction of a
in main()
, [basic.start.term]/4 will not be violated as b
is yet to be destroyed at this point.
If foo()
is invoked prior to the destruction of a
in main()
, it's a different story.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With