【发布时间】:2019-02-04 08:22:53
【问题描述】:
编译如下代码
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
谁能解释一下,为什么包含未使用的标头会更改二进制文件。什么是_GLOBAL__sub_I_main:?
【问题讨论】:
-
C++ 设计理念 你不使用什么,你不花钱 (Foundations of C++, p. 4) 是一个崇高的目标,但是在某些情况下它没有实现。有很多东西可以使 C++ 二进制文件膨胀却毫无用处,而您偶然发现了其中之一。请注意,语言本身并不强制要求它们;这些是优化它们的工具的失败。
-
@MatthieuM。 - 公平地说,这可以称为programming error。有点像制作一个不必要的虚拟功能。目标可以更好地表达为“你不为你不要求的东西付费”。程序员需要知道他们要求什么。
-
@StoryTeller:我不同意。如果优化器删除了对
cout的任何调用实例,因为它证明分支从未被采用;你仍然会得到那些无用的剩菜。如果你改用printf,那么它将被完全消除。