包含 iostream 会导致不同的二进制文件
Include of iostream leads to different binary
编译以下代码
int main() {
return 0;
}
给出集会
main:
xorl %eax, %eax
ret
https://gcc.godbolt.org/z/oQvRDd
如果现在包含iostream
#include <iostream>
int main() {
return 0;
}
此程序集已创建。
main:
xorl %eax, %eax
ret
_GLOBAL__sub_I_main:
subq , %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 , %rsp
jmp __cxa_atexit
已开启全面优化 (-O3)。
https://gcc.godbolt.org/z/EtrEX8
有人可以解释一下,为什么包含未使用的 header 会更改二进制文件。什么是 _GLOBAL__sub_I_main:
?
包括iostream
header的作用是添加一个static的定义std::ios_base::Init
object。此静态 object 的构造函数初始化标准流 objects std::cout
、std::cerr
等等。
这样做的原因是为了避免静态初始化顺序的失败。它确保流 object 跨翻译单元正确初始化。
包含 <iostream>
的每个翻译单元都包含 ios_base::Init
object 的副本:
static ios_base::Init __ioinit;
此 object 用于初始化标准流(std::cout
及其朋友)。此方法称为 Schwarz Counter,它确保标准流在首次使用之前始终被初始化(前提是已包含 iostream
header)。
那个函数 _GLOBAL__sub_I_main
是编译器为每个翻译单元生成的代码,它调用该翻译单元中全局 object 的构造函数,并安排在退出时调用相应的析构函数.此代码在调用 main
之前由 C++ 标准库 start-up 代码调用。
编译以下代码
int main() {
return 0;
}
给出集会
main:
xorl %eax, %eax
ret
https://gcc.godbolt.org/z/oQvRDd
如果现在包含iostream
#include <iostream>
int main() {
return 0;
}
此程序集已创建。
main:
xorl %eax, %eax
ret
_GLOBAL__sub_I_main:
subq , %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 , %rsp
jmp __cxa_atexit
已开启全面优化 (-O3)。 https://gcc.godbolt.org/z/EtrEX8
有人可以解释一下,为什么包含未使用的 header 会更改二进制文件。什么是 _GLOBAL__sub_I_main:
?
包括iostream
header的作用是添加一个static的定义std::ios_base::Init
object。此静态 object 的构造函数初始化标准流 objects std::cout
、std::cerr
等等。
这样做的原因是为了避免静态初始化顺序的失败。它确保流 object 跨翻译单元正确初始化。
包含 <iostream>
的每个翻译单元都包含 ios_base::Init
object 的副本:
static ios_base::Init __ioinit;
此 object 用于初始化标准流(std::cout
及其朋友)。此方法称为 Schwarz Counter,它确保标准流在首次使用之前始终被初始化(前提是已包含 iostream
header)。
那个函数 _GLOBAL__sub_I_main
是编译器为每个翻译单元生成的代码,它调用该翻译单元中全局 object 的构造函数,并安排在退出时调用相应的析构函数.此代码在调用 main
之前由 C++ 标准库 start-up 代码调用。