为什么C/C++的“Hello World”程序大小会达到几千字节?

3

可能是重复问题:
为什么编译后的Java类文件比C编译的文件小?

只是出于好奇,我刚刚编译了C、C++和Java的“Hello Worlds”。

Java类文件非常精简,只有423B,这是因为运行时不包含在二进制文件中。

C和C++的文件却分别为8.5K和9.2K。

它们为什么相对如此大呢? 我一直以为stdio或iostream是动态链接的,并不会增加可执行文件的大小。

那么所有的千字节都来自哪里呢? 通过观察十六进制转储,我发现有很多填充,我猜是为了提高性能。为什么一个二进制格式要这样组织呢?


pmg的链接非常有用!

关于填充,我发现程序段对虚拟内存页面边界(4096字节)的对齐导致它至少为8192字节。

关于mach-o二进制格式(适用于OS X和iOS)

为了获得最佳性能,段应该对齐到虚拟内存页面边界——PowerPC和x86处理器为4096字节。要计算段的大小,请将每个部分的大小相加,然后将总和向上舍入到下一个虚拟内存页面边界(4096字节或4千字节)。使用此算法,段的最小大小为4千字节,之后以4千字节增量调整大小。

引用http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html

下次在提问之前我会先做研究的 ;)


13
你可能会喜欢阅读《为Linux创建非常小的ELF可执行文件的旋风教程》(http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html)。 - pmg
@pmg - 感谢您提供的链接。这是一份令人惊叹的作品,写得非常好。 - Ted Hopp
1
这让我想起了Demo场景,一个64kB的程序可以打开一个带有设置按钮和复选框的窗口,然后播放一个惊人的3D视频,包括声音,超过5分钟长,即使将该视频的一帧作为图像文件存储并进行合理压缩,其大小也会超过64kB。 - vsz
4个回答

5

这是一个关于你所测量的内容的问题。如果它是原始可执行文件大小,那么除了main()代码之外,还包含了大量其他内容。

由于我们在使用共享动态库,因此很多大小将被与符号表、全局偏移量表以及要链接的共享库的描述等相关数据占用 - 共享库本身的代码并不包含在二进制文件中。

iostream库相当庞大,并且还具有静态初始化器,例如初始化coutcerrcin对象。这也是目标文件必须包含的内容。

实际上,大多数额外的大小在应用程序运行时并没有存储在内存中。


2

C & C++是一个完整的独立程序。而Java只是核心代码,需要另一个程序来运行。

一个更小的hello world是使用bash脚本(这也需要另一个程序来运行)。

echo Hello World

总共17个字节,包括一个换行符。


是的和否。C和C ++ 包含可执行代码,但仍然取决于很多管道:操作系统必须解析ELF文件,并且分离库(stdlib)仍必须存在于系统上。但您是对的,它不依赖于单独的解释器/编译器将文件转换为可执行代码。 - jalf

1

一个因素是

#include <iostream>

这会导致许多标准库与您的程序链接。但是不需要担心,这只是一个初始开销,它不会随着程序复杂性或代码长度而增加。无论如何,建议尝试使用UPX


1

因为 stdlib 已经包含在内了,尝试使用 -nostdlib。


没有C标准库,hello world程序将无法链接,或者需要使用原始系统调用进行一些IO操作。这将导致非常小的二进制文件! - marko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接