编译时为什么这个琐碎的程序如此之大?

时间:2012-07-30 16:25:58

标签: c++ ubuntu compilation

我创建了一个包含以下行的文件:

int main() { return 0; }

编译完成后,我惊讶地发现这个简单程序的二进制文件是8328字节!这里发生了什么,这个8328字节的二进制文件在世界上是什么?当然,这个程序可以用几行程序来表达。

注意:我使用以下行编译了这个:

g++ main.cpp

我的g ++版本是g++ (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1

3 个答案:

答案 0 :(得分:29)

这个二进制文件有很多:

  • 使二进制文件自我描述的标题(尝试在其上运行file
  • 符号表,strip工具将为您移除(或与gcc -s链接)
  • 您从不使用的共享库的名称和位置(我的盒子中有五个;尝试使用lddstrings工具)
  • 启动代码,用于加载这些库并设置argcargv,然后调用main
  • 关闭代码,将main的返回值返回给操作系统。

对于漫画效果,请尝试静态链接该程序,其中二进制文件将包含通常动态链接到DLL的函数。 (但是,此选项将简化部署)

答案 1 :(得分:3)

对结果文件进行二进制转储并检查它!

这主要是空地。二进制中的数据被组织成页面(通常,大小为4096或8192字节)。这样页面可以有效memory mapped。通常,第一页包含有关如何加载二进制文件的说明 - 代码位于文件中的此位置并映射到此位置,数据等相同。第二页可能是您的代码,第三页将包含符号和调试信息。每个页面可能都是空的。

答案 2 :(得分:2)

不要打扰。

尝试制作一个不那么简单的程序,你会发现它的大小没有那么大,直到你的代码开始变成各种数百千字节。

简要说明:标准库的一部分构成了操作系统模块和管理程序启动和终止的C ++语义之间的“基础结构”(所有这些都初始化并破坏了全局变量,标准输入和输出等。)

Plus:将C ++符号映射到内存地址的所有内容(如果您不需要删除它) - 请尝试-O3 -s并删除{ {1}}选项)以便调试器可以在执行过程中显示正确的源代码引用。

另外:由于内存的布局方式,二进制文件通常由固定大小的块组成。您的程序甚至可能更短,但必须至少有一个代码段,一个数据段初始值设定项和一个共享段(对于常量值)。