Is it good to print / write in global object constructor or undefined behavior?

#include<iostream> struct A { A () { std::cout << "A::A()\n"; } }; A my_a; // works fine and prints the above line int main () {} 

In accordance with the C ++ standard, the order of global initialization of an object located in several files is not specified.
that is, global objects that are defined in 1 file will call their constructor in order from top to bottom. However, if there are several such files, then which file will be the first to the last, whether the implementation is specific or undefined.

Now std::cout and my_a are both global objects. What does it mean that UB is above the code, is this correct (for example, the initialization fiasco)?
Perhaps the compiler might be smart enough to initialize std objects first before moving on to others. Still for clarity, is there any full-fledged way of logging for global objects lying on multiple files?

+6
source share
1 answer

Yes, this is normal, not UB. The use of streams declared in iostream is clearly defined by the standard.

27.4 Standard iostream objects

2 Objects are built, and associations are established for some time before or during the first when the object of the ios_base::Init class is built , and in any case, before the main body starts execution. 293 Objects are not destroyed during program execution .294 The results of including <iostream> in the translation block should be as if <iostream> determined an instance of ios_base::Init with a static storage duration. In the same way, the whole program should behave as if there was at least one instance of ios_base::Init with a duration of static storage.

Thus, the standard requires that cout initialized before the first creation of ios_base::Init and #include<iostream> , ensuring that it is there. Thus, by turning on iostream, you implicitly define a static instance of ios_base::Init and ensure that cout will work correctly.

Note 294 also explicitly states that constructors and destructors of static objects are allowed to use these objects.

294) Constructors and destructors for static objects can access these objects to read input from stdin or to output output to stdout or stderr.

C ++ 03 Edit: Although all of the above quotes refer to C ++ 11, C ++ 03 does not have a “define ios_base::Init on iostream include” rule. In C ++ 03, there is still a comment about the constructors and destructors of static objects in # 260 instead of 294, so for C ++ 03 it is still allowed to use cout in the constructor of static objects.

+8
source

Source: https://habr.com/ru/post/943686/


All Articles