#include<iostream>
struct A {
A () {
std::cout << "A::A()\n";
}
};
A my_a; // works fine and prints the above line
int main () {}
According to C++ standard, order of global object initialization residing in multiple files is unspecified.
i.e. Global objects which are defined in 1 file will invoke their constructor in top to bottom order. However, if there are multiple such files, then which file will be 1st to last, is implementation defined or unspecified.
Now, std::cout
and my_a
both are global objects. Which means above code is a UB, is it correct (i.e. initialization fiasco)?
Possibly, the compiler might be smart enough to first initialize std
objects before moving to the other ones. Still for the sake of clarity, is there any full proof way to perform logging for global objects lying across multiple files?
Yes it is ok and not an UB. Usage of streams declared in iostream
is clearly defined by standard.
2 The objects are constructed and the associations are established at some time prior to or during the first time an object of class
ios_base::Init
is constructed, and in any case before the body ofmain
begins execution. 293 The objects are not destroyed during program execution.294 The results of including<iostream>
in a translation unit shall be as if<iostream>
defined an instance ofios_base::Init
with static storage duration. Similarly, the entire program shall behave as if there were at least one instance ofios_base::Init
with static storage duration.
Thus standard requires that cout
is initialized prior to first creation of ios_base::Init
and #include<iostream>
guarantees that it will be there. Thus by including iostream you implicitly define ios_base::Init
static instance and guarantee that cout will be working correctly.
Also note 294 explicitly states that constructors and destructors of static objects are are allowed to use those objects.
294) Constructors and destructors for static objects can access these objects to read input from stdin or write output to stdout or stderr.
C++03 Edit:
While all quotes previously given are per C++11 and C++03 doesn't have "define ios_base::Init
on iostream include" rule. C++03 still have comment about constructors and destructors of static objects under #260 instead of 294, so for C++03 it is still allowed to use cout in static object constructor.
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