sch*_*312 37 c++ assembly iostream
编译以下代码
int main() {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
给大会
main:
xorl %eax, %eax
ret
Run Code Online (Sandbox Code Playgroud)
https://gcc.godbolt.org/z/oQvRDd
如果现在iostream包括在内
#include <iostream>
int main() {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这个程序集已创建.
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
Run Code Online (Sandbox Code Playgroud)
打开完全优化(-O3). https://gcc.godbolt.org/z/EtrEX8
有人可以解释一下,为什么包含一个未使用的头更改二进制 什么是_GLOBAL__sub_I_main:?
Max*_*kin 33
每个<iostream>包含的翻译单元都包含一个ios_base::Init对象的副本:
static ios_base::Init __ioinit;
Run Code Online (Sandbox Code Playgroud)
此对象用于初始化标准流(std::cout及其朋友).此方法称为Schwarz Counter,它确保标准流在首次使用之前始终初始化(iostream包括提供的标头).
该函数_GLOBAL__sub_I_main是编译器为每个转换单元生成的代码,该转换单元调用该转换单元中的全局对象的构造函数,并且还安排在退出时调用相应的析构函数调用.调用此代码之前,C++标准库启动代码将调用此代码main.
Sto*_*ica 23
包括iostream头部具有添加静态std::ios_base::Init对象的定义的效果.此静态对象的构造函数初始化标准流对象std::cout,std::cerr依此类推.
它完成的原因是避免静态初始化命令惨败.它确保流对象在翻译单元之间正确初始化.