最小可执行文件的c++ Windows编译器

C++ Windows Compiler for smallest executables

本文关键字:Windows 编译器 c++ 可执行文件      更新时间:2023-10-16

伙计们,我想开始用c++编程。我用vb6, vb.net写了一些程序,现在我想学习c++,我想要的是一个编译器,可以把我的代码编译成最小的windows应用程序。例如,有一个名为PureBasic的Basic语言编译器,可以使Hello world独立应用程序的大小为5 kb,而我编译的简单套接字程序只有12kb(没有任何dll和运行时文件)。我知道这是惊人的,所以我想在c++中有这样的东西。

如果我错了,没有这样的windows编译器,有人能给我一个网站或书,可以教我如何减少c++可执行文件的大小,或者如何使用windows API调用?

以Microsoft Visual c++编译器为例,如果您关闭链接到C运行时(/NODEFAULTLIB),您的可执行文件将小到5KB。

有一个小问题:你将不能使用几乎任何来自标准C或c++库的东西,也不能使用c++的标准特性,如异常处理、newdelete运算符、浮点运算等等。你只需要使用WinAPI直接提供的功能(例如,用CreateFile创建文件,用HeapAlloc分配内存,等等…)。

还值得注意的是,虽然使用这些方法可以用c++创建小的可执行文件,但此时您可能没有使用大多数c++特性。实际上,由于大量使用模板、防止消除死代码的多态性或用于异常处理的堆栈展开表,典型的c++代码有一些明显的膨胀。您最好使用C之类的语言来实现此目的。

多年前我在使用VC6时必须这样做。这是必要的,因为可执行文件将通过有线传输到目标计算机,在那里它将运行。因为它很可能是通过调制解调器连接发送的,所以它需要尽可能小。为了缩小可执行文件,我使用了两种技术:

  1. 不要使用C或c++运行时。告诉编译器不要链接它们。使用Windows API的子集实现所有必要的功能,该子集保证在当时所有版本的Windows (98, Me, NT, 2000)上可用。
  2. 告诉链接器将所有代码和数据段合并为一个。我不记得这个开关,我不知道它是否仍然可能,特别是64位可执行文件。

最终可执行文件大小:~2K

将以下代码的可执行文件大小从Visual c++中的24k减小到1.6k

int main (char argv[]) {
  return 0;
}
  1. 链接器开关(虽然安全对齐建议为512):

/FILEALIGN: 1616/对齐:

  • 链接(在vc++项目属性中):LIBCTINY。自由

  • 附加的pragmas(这将解决Feruccio的建议)

  • 然而,我仍然看到一段ASCII(0)构成了可执行文件的三分之一,以及"Rich"Windows的签名。(我读到后者对于程序执行来说并不是真正需要的)。

    #ifdef NDEBUG
    #pragma optimize("gsy",on)
    #pragma comment(linker,"/merge:.rdata=.data")
    #pragma comment(linker,"/merge:.text=.data")
    #pragma comment(linker,"/merge:.reloc=.data")
    #pragma comment(linker,"/OPT:NOWIN98")
    #endif // NDEBUG
    int main (char argv[]) {
      return 0;
    }
    

    我不知道你为什么在学习语言之前对这种优化感兴趣,但是无论如何…

    用什么编译器并不重要,重要的是如何使用它。选择一个编译器,比如Visual Studio c++或MinGW,并阅读它的文档。您将找到关于如何针对大小或性能优化编译的信息(通常当您针对大小进行优化时,您会损失性能,反之亦然)。

    例如,在Visual Studio中,您可以通过向编译器传递/O1参数(或Project Properties/c - c++/Optimization)来最小化可执行文件的大小。

    也不要忘记在"发布"模式下编译,否则你的可执行文件可能充满了调试符号,这会增加你的可执行文件的大小。

    一台运行Windows的现代台式电脑至少有1Gb内存和一个巨大的硬盘驱动器,担心一个不代表任何实际应用的微不足道的程序的大小是没有意义的。

    在任何语言中,"Hello world"程序的大部分大小都与建立执行环境以及加载和启动代码有关。对于任何重要的应用程序,您应该更多地关注随着添加更多功能而增加的代码大小的速率。从这个意义上说,任何编译器中的c++代码都很可能是非常高效的。也就是说,你的PureBasic程序做的很少,或者什么也不做,可能比一个等效的c++程序要小,但是当你在代码中构建了有用的功能时,情况就不一定是这样了。

    @user: c++确实会生成小的目标代码,但是如果printf()(或cout<<)的代码是静态链接的,那么生成的可执行文件可能会相当大,因为printf()有很多在"hello world"程序中没有使用的功能,所以是多余的。例如,尝试使用puts(),您可能会发现代码更小。

    此外,你确定你是在比较苹果和苹果吗?一些执行环境依赖于动态链接的运行时库或虚拟机,这些运行时库或虚拟机提供的功能可能在c++程序中静态链接。

    我不喜欢回复一个死帖,但是由于没有回复提到这个(除了Mat回复)…

    跟我读:c++ != (vb6 || vb.net || basic)。我不只是提到语法,c++的编码风格通常不同于VB,因为c++程序员试图让东西比VB程序员设计得更好…

    注:不,在c++世界里没有复制粘贴的地方。对不起,我不得不这么说。