【发布时间】:2016-12-31 00:13:27
【问题描述】:
所以这个问题只是出于好奇。 我有一些小程序:
#include <some_header>
void print(){ printf("abc"); } // don't care about main, I'm not gonna run it
然后我将它编译为程序集,一次是 some_header=>iostream,另一次是 some_header=>cstdio 和 gcc.godbolt.org(6.1 for x86_64)和 -O3 -pedantic -std=c++14。看看这个:
.LC0:
.string "abc"
print(): (iostream) or (both included)
movl $.LC0, %edi
xorl %eax, %eax
jmp printf
subq $8, %rsp
movl std::__ioinit, %edi
call std::ios_base::Init::Init()
movl $__dso_handle, %edx
movl std::__ioinit, %esi
movl std::ios_base::Init::~Init(), %edi
addq $8, %rsp
jmp __cxa_atexit
print(): (cstdio)
movl $.LC0, %edi
xorl %eax, %eax
jmp printf
它们之间有很大的不同,前三行是相同的,那么为什么iostream 需要这么多的代码来清理或者这些行只是在做什么?或者只是说 Godbolt 在这项任务上不可靠?
此外,标准似乎并不能保证 printf 可以从 iostream 访问,是否应该依赖这一点?
【问题讨论】:
-
jmp之后的位不是该函数的一部分。它们是另一个功能的一部分,由于某种原因没有标记。 -
@immibis 啊,我应该注意到了,但有趣的是,即使我只包含
iostream,即使使用-Os,这部分代码也存在,所以我怀疑这是一些动态初始化程序或类似的东西。