When an executable (e.g. for bare metal environment) is statically linked with libc++ the following code might not work as expected:
#include <iostream> class Foo { public: Foo(int n) { std::cout << "Hello World - " << n << std::endl; } }; Foo f(5); int main() { return 0; }
The program hangs or crashes because 'std::cout' is not initialized before 'Foo f(5)'.
The standard says:
27.3 Standard iostream objects
Header <iostream> synopsis
(2) ... The objects are constructed, and the associations are established at some time prior to or during first
time an object of class basic_ios<charT,traits>::Init is constructed, and in any case before the body of main
begins execution [264]. The objects are not destroyed during program execution [265].
And footnote 265 says:
Constructors and destructors for static objects can access these objects to read input from stdin or write output
to stdout or stderr.
The similar issue was raised more than year ago. A patch was proposed but not committed. See discussion of it here:
initial patch
review, suggestion for #ifdef
The proposed patch caused initialization/deinitialization of the std streams as many times as the static Init objects were created.
The current patch fixes this issue. A number of uses is counted by means of __shared_count. It is used instead of a 'int' variable because it is thread-safe. The standard allows multi-threaded initialization of static objects from different compilation modules.