编译后二进制文件的大小如何取决于所使用的库?c / c++
how does the size of compiled binaries depend on the used libraries? c/c++
上周我在网上发现了一个简单的游戏killallcops.exe。我研究了二进制文件,想知道为什么这个程序这么大。(约460 k)
所以我用iostream重写了游戏
#include <iostream>
int main(){
std::cout << "All cops are killed.nCongratulations";
std::cin.ignore();
return 0;
}
用g++编译也得到了460k。
我真的很奇怪为什么这个东西这么大,用stdio重写了它
#include <stdio.h>
int main(){
printf("All cops are killed.nCongratulations");
while(getchar() != 'n'){}
return 0;
}
用GCC编译得到13k。
我知道iostream比stdio有更多的能力(比如类型安全),因此它本身要大得多,但是为什么这会导致更大的二进制文件,当使用iostream时是否有减少大小的解决方案,例如只使用它的特定部分?
在cygwin下使用GCC 3.4.4我将充实我的评论作为答案:
<iostream>
有很多内部依赖,即使使用一个简单的cout调用。它带来了许多其他需要工作的代码/头(包括模板代码等)。首先,让我们假设引入<iostream>
的大小在一个重要的应用程序中可能不是很重要。
你可以相信编译器/链接器知道他们在做什么,但是如果你想减少二进制文件的大小,尝试使用像gcc -s
这样的选项,它会去除符号,或者像-Os
这样的标志,它会尝试优化二进制文件的大小。
我怀疑你的很多二进制大小问题实际上来自其他东西:一个静态链接的libstdc++
。
如果你在Windows上使用MinGW,请注意,直到最近,他们的GCC工具链实现还没有动态链接的libstdc++
;相反,所有c++构建都在libstdc++
中静态链接,这将大大增加二进制文件的大小。
下面是g++
为您的代码生成的二进制文件的大小的比较,在Linux上,使用GCC 4.6.1。在这些构建中没有执行优化或符号剥离。
λ > ls -lh a.out
-rwxr-xr-x 1 billylee billylee 6.1K Dec 24 10:37 a.out
这是GCC生成的
λ > ls -lh trial
-rwxr-xr-x 1 billylee billylee 4.9K Dec 24 10:41 trial
g++版本比gcc版本大一点,但不会大100倍。
编辑:如果你正在使用MinGW -这里有一个最近的线程:如何减少由MinGW编译器产生的可执行文件的大小?
MinGW gcc 4.5.0+默认使用动态链接,如果您使用MinGW,请检查您的版本。
我没有在Linux上复制(大小为9K和8K)。我的猜测是,对于c++,您是静态链接标准库,而对于C,您是动态链接它。
答案是:没有那么大。在Linux上的c++ 4.6上编译,没有编译选项,它是9040字节。剥离后为6312字节。
你使用了哪些编译选项,你使用的是哪个版本的g++ ?
这可能是由于您的平台,也许如果您使用MinGW,它是静态链接运行时的大小。
另外,#import
是已弃用的仅支持g++的语言扩展,您应该使用#include
- 重载运算符new[]的行为取决于析构函数
- 新的放置取决于 iostream
- Writefile() 无法写入数据,具体取决于数据的长度
- ASIO signal_set多个 IO 线程不可靠,具体取决于代码顺序?
- SFINAE是否取决于类型推断?
- 将强制转换简化为取决于参数的类型
- 修复"-Wunused-parameter"取决于预处理器条件的警告
- 内存中类位置的成员是否取决于类成员在类定义中的位置?
- 奇怪的Arduino C++编译错误取决于文件位置
- CUDA 的性能取决于声明变量
- 我想要一个具有子函数的函数访问相同的命名函数,而不使用它取决于其子类的类
- 条件跳转或移动取决于 std::wistringstream 的未初始化值
- cpp 模板专用化,错误说参数 1 的类型为 T,这取决于参数 T
- 为什么c++中类的大小取决于数据成员的公共/私有状态
- 编译时函数的选择取决于类型大小
- memcpy是否取决于源指针和目标指针的类型
- 矩阵乘法的速度取决于愚蠢的事情
- 如果条件取决于模板类型并且在编译时已知,是否可以保证C++编译器不会生成分支?
- 求解未校正序列 (4,3,2,1,5) 并将其更改为校正序列取决于我的建议
- 初始化数据成员取决于构造函数中的条件