Similar to this question, but now I have two translation units:
// a.cpp
#include <iostream>
void print_hello() {
std::cout << "hello\n";
}
// b.cpp
void print_hello();
struct StaticObject {
StaticObject() {
print_hello();
}
} static_object;
int main() {
}
If I compile these two locally with g++ -std=c++17 a.cpp b.cpp, the resulting a.exe crashes. My compiler version is g++ (Rev2, Built by MSYS2 project) 10.3.0 on Windows.
I am also able to reproduce this behavior by compiling g++ -std=c++17 b.cpp a.cpp with g++-10 (Ubuntu 10.3.0-1ubuntu1~20.04) 10.3.0
I believe it is because b.cpp does not include <iostream> and static_object gets constructed before anything in a.cpp, corresponding std::ios_base::Init provided by <iostream> in particular. Hence, when print_hello() is called, std::cout is not initialized yet, hence the crash.
The final question being: is it guaranteed by C++17 that std::cout is initialized before all "user-provided" (for the lack of better word) objects with static storage duration are initialized? Experiments suggest that it is not.