¿Se garantiza la inicialización de std :: cout?

Lo que sé sobre C ++ es que no debe suponerse el orden de las construcciones (y destrucciones) de las instancias globales.

Mientras escribo código con una instancia global que usa std::cout en el constructor y el destructor, recibí una pregunta.

std::cout es también una instancia global de iostream. ¿Está garantizado que std::cout se inicialice antes que cualquier otra instancia global?

Escribí un código de prueba simple y funciona perfectamente, pero aún no sé por qué.

 #include  struct test { test() { std::cout << "test::ctor" << std::endl; } ~test() { std::cout << "test::dtor" << std::endl; } }; test t; int main() { std::cout << "Hello world" << std::endl; return 0; } 

Imprime

 test::ctor Hello world test::dtor 

¿Hay alguna posibilidad de que el código no se ejecute como se esperaba?

La respuesta difiere según si usa C ++ 03 o C ++ 11.

En C ++ 11, se garantiza que su código funcionará, pero en C ++ 03 no está especificado; su única garantía es que para cuando se ingrese main() , las transmisiones estándar se habían inicializado. (Dicho esto, todas las implementaciones convencionales las inicializan antes de ejecutar cualquier inicialización dinámica, lo que les permite utilizarlas).

Puede forzar la inicialización mediante la construcción de un objeto std::ios_base::Init , así:

 #include  struct test { test() { std::cout << "test::ctor" << std::endl; } ~test() { std::cout << "test::dtor" << std::endl; } private: std::ios_base::Init mInitializer; }; test t; int main() { std::cout << "Hello world" << std::endl; return 0; } 

Ahora cuando se construyen las test , inicializa mInitializer y garantiza que las transmisiones estén listas para usar.

C ++ 11 corrigió este comportamiento ligeramente molesto al actuar como si cada instancia de #include fuera seguida por static std::ios_base::Init __unspecified_name__; . Esto garantiza automáticamente que las transmisiones estén listas para usar.

De acuerdo con §27.3 / 2 :

Los objetos [std :: cin, std :: cout, etc.] se construyen, y las asociaciones se establecen en algún momento antes o durante la primera vez que se construye un objeto de la clase ios_base :: Init, y en cualquier caso antes del cuerpo de main comienza la ejecución.

Su pregunta es sobre el orden de construcción de los objetos estáticos. Creo que la especificación del lenguaje lo deja indefinido.

GCC tiene el atributo init_priority para jugar con la orden.

Y creo que no deberías preocuparte tanto en la práctica.