编译以下代码
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 $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
完全优化已打开(-O3)。
https://gcc.godbolt.org/z/EtrEX8
有人可以解释一下,为什么包括未使用的 header 会更改二进制文件。什么是
_GLOBAL__sub_I_main:
? 最佳答案
每个包含<iostream>
的翻译单元都包含ios_base::Init
对象的副本:
static ios_base::Init __ioinit;
该对象用于初始化标准流(
std::cout
及其 friend )。此方法称为Schwarz Counter,它确保标准流始终在首次使用之前进行初始化(已提供了iostream
header )。该函数
_GLOBAL__sub_I_main
是编译器为每个翻译单元生成的代码,该代码调用该翻译单元中的全局对象的构造函数,并安排在导出处调用相应的析构函数调用。在调用main
之前,此代码由C++标准库启动代码调用。关于c++ - 包含iostream导致不同的二进制文件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52079248/