通过包含iostream
在源文件中,编译器需要生成代码来设置和拆除 C++ 标准 I/O 库。您可以通过查看 的输出来看到这一点nm
,它显示了目标文件上的符号(通常是函数):
$ nm --demangle test_with_iostream
08049914 d _DYNAMIC
08049a00 d _GLOBAL_OFFSET_TABLE_
08048718 t global constructors keyed to main
0804883c R _IO_stdin_used
w _Jv_RegisterClasses
080486d8 t __static_initialization_and_destruction_0(int, int)
08048748 W MyClass::MyClass()
U std::string::size() const@@GLIBCXX_3.4
U std::string::operator[](unsigned int) const@@GLIBCXX_3.4
U std::ios_base::Init::Init()@@GLIBCXX_3.4
U std::ios_base::Init::~Init()@@GLIBCXX_3.4
080485cc t std::__verify_grouping(char const*, unsigned int, std::string const&)
0804874e W unsigned int const& std::min<unsigned int>(unsigned int const&, unsigned int const&)
08049a3c b std::__ioinit
08049904 d __CTOR_END__
... (remaining output snipped) ...
(--demangle
获取编译器“修改”的 C++ 函数名称并生成更有意义的名称。如果函数包含在可执行文件中,第一列是地址。第二列是类型。“t”是“ text" 段。"U" 是从其他地方链接的符号;在这种情况下,来自 C++ 共享库。)
将此与从源文件生成的函数进行比较,但不包括iostream
:
$ nm --demangle test_without_iostream
08049508 d _DYNAMIC
080495f4 d _GLOBAL_OFFSET_TABLE_
080484ec R _IO_stdin_used
w _Jv_RegisterClasses
0804841c W MyClass::MyClass()
080494f8 d __CTOR_END__
... (remaining output snipped) ...
当您的源文件包含在内iostream
时,编译器会生成几个没有iostream
.
当您的源文件仅包含stdio.h
时,生成的二进制文件类似于不包含 的测试iostream
,因为 C 标准 I/O 库不需要在 C 动态库中已经发生的事情之外进行任何额外的初始化。您可以通过查看nm
相同的输出来看到这一点。
但是,一般来说,试图根据可执行文件的大小来直观地了解特定源文件生成的代码量是没有意义的。有太多东西可以改变,如果编译器包含调试信息,源文件的位置等简单的事情可能会改变二进制文件。
您可能还会发现objdump
在您的可执行文件的内容中四处寻找很有用。