【问题标题】:Why is this trivial program so large when compiled?为什么这个微不足道的程序编译后会这么大?
【发布时间】:2012-07-30 16:25:58
【问题描述】:

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

int main() { return 0; }

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

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

g++ main.cpp

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

【问题讨论】:

  • 你在编译什么平台? IE。 Windows、Linux?
  • @Matthew 我在 Linux 上。尤其是 64 位 Ubuntu。
  • @CoryKlein,这就是 larsmans 所说的“启动代码”。
  • 你说8K大? hello world 在 MinGW 上是 500K ;)

标签: c++ ubuntu compilation


【解决方案1】:

该二进制文件中有很多内容:

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

为了喜剧效果,请尝试静态链接该程序,您的二进制文件将包含通常动态链接到 DLL 的函数。 (但是,此选项将简化部署)

【讨论】:

    【解决方案2】:

    对生成的文件进行二进制转储并检查它!

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

    【讨论】:

    • 嗯,很有趣。我确实用十六进制编辑器查看了它,其中有一个部分是空的,但它只包含文件的 46%。
    【解决方案3】:

    不要打扰。

    试着做一个不那么琐碎的程序,你会发现大小并没有那么不同,直到你的代码开始变成数百千字节。

    简而言之:标准库的一部分构成了操作系统模块之间的“基础设施”和管理程序启动和终止的 C++ 语义(所有这些都初始化和销毁​​全局变量,标准输入和输出等)

    另外: 将 C++ 符号映射到内存地址的所有内容,(如果您不需要删除它 - 尝试使用 -O3 -s 并删除 -g 选项)这样调试器就可以在整个执行过程中显示正确的源代码引用。

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

    【讨论】:

      猜你喜欢
      • 2021-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-16
      • 1970-01-01
      • 2010-12-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多