GCC:空程序== 23202字节?

Geo*_*rge 14 c c++ linker gcc tdm-mingw

test.c:

int main()
{
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我没有使用任何标志(我是gcc的新手),只是命令:

gcc test.c
Run Code Online (Sandbox Code Playgroud)

我在win32上使用了最新的GDM TDM版本.生成的可执行文件几乎是23KB,对于空程序来说太大了.

如何减小可执行文件的大小?

Phi*_*ler 37

不要遵循它的建议,但为了娱乐起见,请阅读关于制作尽可能小的ELF二进制文件的"故事".

  • @Novelocrat是的,我赞成,因为你发布的链接非常有趣,不是因为我认为OP应该做这样的事情.我希望*其他大多数赞成票也是出于同样的原因. (2认同)

may*_*eye 21

如何减小尺寸?

  • 不要这样做.你只是在浪费时间.
  • 使用-s标志去除符号(gcc -s)


Kir*_*sky 11

默认情况下,某些标准库(例如C运行时)与您的可执行文件链接.查看钥匙--nostdlib --nostartfiles --nodefaultlib以了解详情.此处描述的链接选项.

对于真正的程序,第二个选项是尝试优化选项,例如-Os(优化大小).


Nor*_*sey 11

放弃. 在x86 Linux上,gcc 4.3.2生成一个5K二进制文件.可是等等!这是动态链接!在静态链接二进制是半个多世纪MEG:516K.放松并学会与臃肿一起生活.

而且他们说Modula-3永远不会去任何地方因为200K hello world binary!


如果您想知道发生了什么,Gnu C库的结构可以包括某些功能,无论您的程序是否依赖于它们.这些功能包括例如琐事如malloc和free,dlopen的,一些字符串处理,以及整个bucketload的东西,似乎与语言环境和国际化的事,虽然我无法找到任何相关的手册页.

为需要最少服务的程序创建小型可执行文件不是 glibc 的设计目标.公平地说,它也不是我曾经使用过的每个运行时系统的设计目标(大约六个).


Wim*_*ink 7

实际上,如果你的代码什么都不做,那么编译器是否仍然可以创建一个可执行文件呢?;-)

好吧,在Windows上,任何可执行文件仍然有一个大小,虽然它可以合理地小.使用旧的MS-DOS系统,完整的无操作应用程序只需几个字节.(我认为四个字节使用21h中断来关闭程序.)然后,这些应用程序被直接加载到内存中.当EXE格式变得更受欢迎时,情况发生了一些变化.现在,可执行文件包含有关进程本身的其他信息,例如代码和数据段的重定位以及一些校验和和版本信息.Windows的引入为格式添加了另一个标题,告诉MS-DOS它无法执行可执行文件,因为它需要在Windows下运行.Windows会毫无问题地识别它.当然,可执行格式也扩展了资源信息,如位图,图标和对话框形式等等.

现在,无操作可执行文件的大小将介于4到8千字节之间,具体取决于您的编译器以及您用于减小其大小的每种方法.这将是UPX实际上会产生更大可执行文件的大小!可能会添加可执行文件中的其他字节,因为您在代码中添加了某些库.特别是具有初始化数据或资源的库将添加相当多的字节.添加调试信息也会增加可执行文件的大小.

虽然这一切都在减小尺寸方面做得很好,但你可能会怀疑是否继续担心应用程序的膨胀是否可行.现代硬盘将分段文件分割,对于真正大的磁盘,差异将非常小.但是,将大小保持尽可能小的麻烦将减慢开发速度,除非您是熟悉这些优化的专家开发人员.这些类型的优化不会提高性能,并且考虑到大多数系统的平均磁盘空间,我不明白为什么它是实用的.(尽管如此,我确实以类似的方式优化了我自己的代码,但是再次,我对这些优化很有经验.)


EXE标题感兴趣?它以字母MZ开头,代表"Mark Zbikowski".第一部分是可执行文件的旧式MS-DOS标头,用作MS-DOS的存根,说该程序不是 MS-DOS可执行文件.(在二进制文件中,你可以找到文本'这个程序不能在DOS模式下运行'.这基本上就是它所做的全部:显示该消息.接下来是PE头,Windows将识别并使用而不是MS-DOS它以可移植可执行文件的字母PE开头.在第二个标题之后,将有可执行文件本身,分为几个代码和数据块.标题包含特殊的重新分配表,告诉操作系统在哪里加载特定的块.如果你可以保持这个限制,最终的可执行文件可以小于4 KB,但90%将是标题信息,没有功能.

  • 对于DOS应用程序,一个简单的ret将会做.也就是说,1个字节. (3认同)