我编写了以下 C++ 程序
class MyClass {
public:
int i;
int j;
MyClass() {};
};
int main(void)
{
MyClass inst;
inst.i = 1;
inst.j = 2;
}
我编译了。
# g++ program.cpp
# ls -l a.out
-rwxr-xr-x 1 root wheel 4837 Aug 7 20:50 a.out
然后,我在源文件中#include
d头文件iostream,我再次编译。
# g++ program.cpp
# ls -l a.out
-rwxr-xr-x 1 root wheel 6505 Aug 7 20:54 a.out
正如预期的那样,文件大小增加了。
我还写了下面的C程序
int main(void)
{
int i = 1;
int j = 2;
}
我编译了
# gcc program.c
# ls -l a.out
-rwxr-xr-x 1 root wheel 4570 Aug 7 21:01 a.out
然后,我#include
d头文件stdio.h,我再次编译
# gcc program.c
# ls -l a.out
-rwxr-xr-x 1 root wheel 4570 Aug 7 21:04 a.out
奇怪的是,可执行文件的大小保持不变。
最佳答案
通过在源文件中包含 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++ 函数名称并生成更有意义的名称。如果函数包含在可执行文件中,则第一列是地址。第二列column 是类型。“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
对于查看可执行文件的内容很有用。
关于c++ - 为什么 C 头文件不增加二进制文件的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1246260/