sirve - que es cout en c++
Incluir de iostream conduce a diferentes binarios. (2)
Compilando el siguiente código
int main() {
return 0;
}
da la asamblea
main:
xorl %eax, %eax
ret
https://gcc.godbolt.org/z/oQvRDd
Si ahora está incluido iostream
#include <iostream>
int main(){
return 0;
}
Se crea este ensamblaje.
main:
xorl %eax, %eax
ret
_GLOBAL__sub_I_main:
subq $8, %rsp
movl $_ZStL8__ioinit, %edi
call std::ios_base::Init::Init() [complete object constructor]
movl $__dso_handle, %edx
movl $_ZStL8__ioinit, %esi
movl $_ZNSt8ios_base4InitD1Ev, %edi
addq $8, %rsp
jmp __cxa_atexit
La optimización completa está activada (-O3). https://gcc.godbolt.org/z/EtrEX8
Alguien puede explicar por qué incluir un encabezado no utilizado cambia el binario. ¿Qué es _GLOBAL__sub_I_main:
:?
Cada unidad de traducción que incluye <iostream>
contiene una copia del objeto ios_base::Init
:
static ios_base::Init __ioinit;
Este objeto se utiliza para inicializar las secuencias estándar ( std::cout
y sus amigos). Este método se llama Schwarz Counter y garantiza que las secuencias estándar siempre se inicialicen antes de su primer uso (siempre que se haya incluido el encabezado de iostream
).
Esa función _GLOBAL__sub_I_main
es el código que el compilador genera para cada unidad de traducción que llama a los constructores de objetos globales en esa unidad de traducción y también organiza la invocación de las llamadas del destructor correspondiente al salir. Este código es invocado por el código de inicio de la biblioteca estándar de C ++ antes de llamar a main
.
Incluir el encabezado iostream
tiene el efecto de agregar la definición de un objeto std::ios_base::Init
estático. El constructor de este objeto estático inicializa los objetos de secuencia estándar std::cout
, std::cerr
y así sucesivamente.
La razón por la que se hace es evitar el fiasco de orden de inicialización estática. Asegura que los objetos de flujo se inicialicen correctamente en las unidades de traducción.