我正在使用GCC 4.8.2在我的Windows 8.1,Intel i7-3517U 64位笔记本电脑上测试这个简单的c ++代码。
#include<iostream>
using namespace std;
int main(int argc, char **argv){
cout << "This test code will simply display any arguments passed." << endl ;
for(int i=0; i<argc; i++){
cout << argv[i] << endl ;
}
return 0 ;
}
令人惊讶的是,编译后,可执行文件的结果为 5905KB 。出于好奇,我尝试在Linux Fedora 20 64位机器上使用相同的GCC版本编译相同的文件。可执行文件只是 9KB 。
使用g++ -Ox -o fileWithOx.exe file.cpp
(x = 1,2,3,s)进行各种优化后,Windows可执行文件的大小几乎相同。在做了一些研究之后,在MinGW's advise之后我尝试使用strip g++ -s -o fileWithStrip.exe file.cpp
编译它们而没有调试信息,但是可执行文件仍然 597KB 大。
另一方面,对于相同的选项,Linux可执行文件只有 6-13KB 。
做一些实验,some more research&amp; stack overflowing,我几乎确信巨大的大小是由于 iostream 链接到许多其他头文件和/或生成一些初始化代码。
但我怀疑是iostream既可以在Windows中使用,也可以在Linux中使用。那为什么这么大的差异呢?我知道Windows和Linux可执行文件的工作方式不同。 但是大了655倍,这不是有点极端吗?
答案 0 :(得分:5)
差异可能不是由于编译而是链接版本阶段。
首先尝试仅编译,使用-c
停止命令,例如类似于Unix的g++ -c code.cpp
并在Windows环境中找到等效的标志。然后比较目标文件,它们应该是几乎相同的大小。这些目标文件(.o
扩展名)仅包含代码到机器代码的转换。大小可能会有所不同,比如可能是2或3,但这是不相关的。
发生的事情是Windows的编译器可能在某些库上使用静态链接,因此可执行文件包含您在库中使用的代码。在Unix上,编译器可能会动态地链接所有内容,这表示库将在运行时加载而不包含在可执行文件中。
请参阅编译器文档以了解如何强制执行静态/动态链接。您应该知道,某些环境可能无法提供这两种类型的库......
答案 1 :(得分:2)
使用mingw g ++版本4.7.2在Windows下构建你的程序 - 我只获得10kb。不知道你是怎么设法把它膨胀到超过5MB。这是我在Code :: Blocks 13.12中按下Ctrl-F11时的cmd行和输出:
mingw32-g ++。exe -Wall -fexceptions -O2 -I“C:\ Program Files(x86)\ CodeBlocks \ MinGW \ include”-c C:\ Users \ enhzflep \ Documents \ code \ 001-sizeTestDeleteMe \ main .cpp -o obj \ Release \ main.o mingw32-g ++。exe -o bin \ Release \ 001-sizeTestDeleteMe.exe obj \ Release \ main.o -s
输出文件是bin \ Release \ 001-sizeTestDeleteMe.exe,大小为10.50 KB
答案 2 :(得分:1)
抱歉,我现在没有任何Windows框,但如果我相信这篇文章,
也许是因为你的Windows可执行文件静态链接到Mingw编译器套件附带的libstdc++.a
,而Linux版本动态链接到像/usr/lib64/libstdc++.so.6
这样的东西。后者是大多数Linux发行版的标准组件之一,可以通过动态链接器进行搜索,因此Linux g++
可以安全地依赖它。但前者不是,所以也许Mingw g++
决定采用静态链接。
以下文章(在Mingw GCC 4.4上)说,您可以告诉Mingw g++
动态链接libstdc++.dll
与cmd行选项-lstdc++_s
仅供参考,这就是我的Debian盒子上的小型C ++ exe与libstdc++.so.6
动态链接的方式:
$ ldd valueInit
linux-vdso.so.1 (0x00007fff641fe000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f20618e2000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f20615e4000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f20613cd000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2061021000)
/lib64/ld-linux-x86-64.so.2 (0x00007f2061c12000)
$ LANG=C ls -lH /usr/lib/x86_64-linux-gnu/libstdc++.so.6
-rw-r--r-- 1 root root 953K Jan 6 12:24 /usr/lib/x86_64-linux-gnu/libstdc++.so.6
libstdc++.so.6
确实包含许多iostream
函数等的定义。
$ readelf -sW /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep stream | c++filt | head -3
135: 0000000000084360 51 FUNC WEAK DEFAULT 12 std::money_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >::get(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> >, bool, std::ios_base&, std::_Ios_Iostate&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&) const@@GLIBCXX_3.4
137: 00000000002e8ff0 24 OBJECT WEAK DEFAULT 23 typeinfo for std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >@@GLIBCXX_3.4
138: 000000000009f1d0 15 FUNC WEAK DEFAULT 12 std::num_put<wchar_t, std::ostreambuf_iterator<wchar_t, std::char_traits<wchar_t> > >::put(std::ostreambuf_iterator<wchar_t, std::char_traits<wchar_t> >, std::ios_base&, wchar_t, void const*) const@@GLIBCXX_3.4