大家注意到没有?gnu的c++编译器编成的文件怎么很大呀?

发表于:2007-05-26来源:作者:点击数: 标签:
同样的“helloworld”源码用系统的c++编译器和gnu的c++编译器生成的文件相差很大呀?(scounix下都是elf格式) 系统编译出文件:35524(CCa.cpp-oa) gnu编译出文件:776076(g++a.cpp-oa) 剥离符号表后文件大小分别为:24428和108112 怎么让g++编译的文件

同样的“hello world”源码用系统的c++编译器和gnu的c++编译器生成的文件相差很大呀? (scounix下都是elf格式)
系统编译出文件:  35524  (CC a.cpp -o a)  
gnu 编译出文件:  776076 ( g++ a.cpp -o a)
剥离符号表后文件大小分别为:24428 和  108112
怎么让g++编译的文件小些呢?加优化参数也变化不大。

   

 qjlemon 回复于:2003-07-31 16:51:27
strip
编译的时候不加-g

 li2002 回复于:2003-07-31 16:57:34
编译时没加-g 
strip我知道,后面的数据就是strip的结果。

 sunlan 回复于:2003-07-31 17:38:26
比较过cc和gcc所用的libc.a吗?

 qjlemon 回复于:2003-07-31 17:40:17
感觉有点象是做的静态链接喔! ldd一下看看?

 li2002 回复于:2003-07-31 19:41:43
恩,用ldd 看了,是动态连接的,
用CC:
dynamic linker:a: file loaded: /usr/lib/libcrypt.so
dynamic linker: a: file loaded: /usr/lib/libc.so.1
用g++:
dynamic linker: a: file loaded: /usr/lib/libc.so.1
怎么回事呢,g++把libcrypt.so静态连接了吗,没指定这个东东阿,这是个什么库呢,我就是一个简单的hello,world程序,那里用到这个的阿!
那位告诉偶一下,不懂,谢谢!!

 无双 回复于:2003-07-31 19:57:46
libcrypt.so

这个是加密库 你有没有用到DES之类的
简单的程序应该不会吧
其它平台也不会区别那么大

 无双 回复于:2003-07-31 19:58:23
最好的办法是写一个最简单的程序

main(){
printf("hello world\n");
}

然后看看是多大 比较一下

 li2002 回复于:2003-07-31 20:02:47
老大,我就是简单的程序,主要是比较一下编译出的文件大小。
[code:1:7ac296e1cc]
#include<iostream.h>
main()
{
cout<<"hello world"<<endl;
}
[/code:1:7ac296e1cc]
真是不解,没用什么加密的函数阿。

 li2002 回复于:2003-07-31 20:09:03
偶发现用cc或CC编译出的elf文件都是动态连接上面提到的两个库。
而用gcc或g++的只有一个库。
gcc比cc编译出的东西略大一些,可以接受,但g++比CC编译出的大好几倍阿,究竟gnu的编译器有什么优势呢,至少文件太大了,不能理解。

 无双 回复于:2003-07-31 20:16:04
G++的语法分析等是不一样的

也许iostream里面使用了某些东西
g++编译时就选进去了吧

相差太大了确实有问题

 li2002 回复于:2003-07-31 23:09:55
哎,没人研究过吗?

 stevenyi 回复于:2003-07-31 23:41:28
主要是g++的libstdc++库比较大;这可以理解,毕竟g++支持的功能比sco c++多得多.另外比较最简单的程序没什么意义,因为这实际比较的是c++库的大小(如果是静态连接的话)

 stevenyi 回复于:2003-07-31 23:43:40
我在FreeBSD上用g++编译一个Hello World c++程序,动态连接的话只有6k多,而静态连接的话则要地600k多

 li2002 回复于:2003-08-01 00:11:47
啊,是吗?g++怎么编成动态连接的,偶没加参数默认是静态的吗?

 stevenyi 回复于:2003-08-01 00:18:00
SCO上的gcc/g++好象只能静太连接

 neosnake 回复于:2003-08-01 00:20:45
默认应该是动态的.

 li2002 回复于:2003-08-01 07:30:05
g++动态连接编译是什么参数?

 stroustrup 回复于:2003-08-01 10:16:38
你个头,上次就说了放弃,你还做。

 li2002 回复于:2003-08-01 12:35:16
楼上不要乱灌水

 蓝色键盘 回复于:2003-08-02 14:16:44
[quote:f2c1ff76db="li2002"]啊,是吗?g++怎么编成动态连接的,偶没加参数默认是静态的吗?[/quote:f2c1ff76db]     

如果系统存在动态库,并且可以访问到,例如Libc.so,那么优先处理动态库,除非编译指定要静态库。

 蓝色键盘 回复于:2003-08-02 14:20:41
[quote:814b2ea470="li2002"]真是不解,没用什么加密的函数阿。[/quote:814b2ea470]     

[code:1:814b2ea470]#include<iostream.h> 
main() 

cout<<"hello world"<<endl; 

[/code:1:814b2ea470]

加和不加头文件区别也存在。如果加那么头文件相关的信息要连接进去的,如果不加编译程序找标准库ld。

去掉头文件看看结果,更有意思。

 qjlemon 回复于:2003-08-02 17:21:51
cout不是那么简单的,把什么都去掉,只留一个空空的main在那里会如何呢?

 蓝色键盘 回复于:2003-08-02 19:15:29
蜗牛 啊,自己找个环境试试呀

呵呵

 qjlemon 回复于:2003-08-02 19:25:22
响应老大的号召  
测试环境:
Redhat Linux 7.2 
[code:1:b71dbd99dc]
[billing@bfdx]$ gcc -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.96/specs
gcc version 2.96 20000731 (Red Hat Linux 7.1 2.96-98)
[billing@bfdx]$ whereis cc
cc: /usr/bin/cc
[billing@bfdx]$ whereis g++
g++: /usr/bin/g++ /usr/share/man/man1/g++.1.gz
[billing@bfdx]$ ls -l /usr/bin/g++
-rwxr-xr-x    4 root     root        80172 Sep  4  2001 /usr/bin/g++*
[billing@bfdx]$ ls -l /usr/bin/cc
lrwxrwxrwx    1 root     root            3 Jun 24 22:00 /usr/bin/cc -> gcc*
[billing@bfdx]$ whereis gcc
gcc: /usr/bin/gcc /usr/share/man/man1/gcc.1.gz
[billing@bfdx]$ ls -l /usr/bin/gcc
-rwxr-xr-x    2 root     root        78892 Sep  4  2001 /usr/bin/gcc*
[/code:1:b71dbd99dc]

[code:1:b71dbd99dc]
main()
{
}
[billing@bfdx]$ cc test.cpp
[billing@bfdx]$ ls -l
total 20
-rwxr-xr-x    1 billing  users       13555 Aug  2 19:23 a.out*
-rw-r--r--    1 billing  users          11 Aug  2 19:22 test.cpp
[billing@bfdx]$ ldd a.out
        libc.so.6 => /lib/i686/libc.so.6 (0x40018000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
[billing@bfdx]$ g++ test.cpp -o a1.out
[billing@bfdx]$ ls -l
total 36
-rwxr-xr-x    1 billing  users       13555 Aug  2 19:23 a.out*
-rwxr-xr-x    1 billing  users       13805 Aug  2 19:23 a1.out*
-rw-r--r--    1 billing  users          11 Aug  2 19:22 test.cpp
[billing@bfdx]$ ldd a1.out
        libstdc++-libc6.2-2.so.3 => /usr/lib/libstdc++-libc6.2-2.so.3 (0x40018000)
        libm.so.6 => /lib/i686/libm.so.6 (0x4005a000)
        libc.so.6 => /lib/i686/libc.so.6 (0x4007d000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
[/code:1:b71dbd99dc]
看来主要就是库的不同喔

 蓝色键盘 回复于:2003-08-02 19:33:00
[quote:25af43959e="qjlemon"]看来主要就是库的不同喔[/quote:25af43959e]     

蜗牛,怎么不显示
#include <*.h>
void main()
{
}
的结果呀?

 qjlemon 回复于:2003-08-02 19:40:28
test.cpp:
[code:1:825229479a]
#include<iostream.h> 
main()
{
}
[/code:1:825229479a]
  [code:1:825229479a]
 [billing@bfdx]$ g++ test.cpp -o a2.out
[billing@bfdx]$ ls -l a2.out
-rwxr-xr-x    1 billing  users       13805 Aug  2 19:37 a2.out*
[billing@bfdx]$ ldd a2.out
        libstdc++-libc6.2-2.so.3 => /usr/lib/libstdc++-libc6.2-2.so.3 (0x40018000)
        libm.so.6 => /lib/i686/libm.so.6 (0x4005a000)
        libc.so.6 => /lib/i686/libc.so.6 (0x4007d000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
[billing@bfdx]$ cc test.cpp -o a3.out
[billing@bfdx]$ ls -l a3.out
-rwxr-xr-x    1 billing  users       13555 Aug  2 19:37 a3.out*
[billing@bfdx]$ ldd a3.out
        libc.so.6 => /lib/i686/libc.so.6 (0x40018000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
[/code:1:825229479a]
变化不大呀!大概看了一下iostream.h,有一些代码,不过估计占不了太大的尺寸啊
模板库如果不用的话就不会占多少空间吧  多半是的

 蓝色键盘 回复于:2003-08-02 19:45:15
那个ANSI C的代码测试看看。

结构又是什么?

 qjlemon 回复于:2003-08-02 19:52:08
差不多喔!
test.cpp:
[code:1:7eec1cd136]
#include <stdio.h>
main()

printf("hello world\n"); 

[/code:1:7eec1cd136]
[code:1:7eec1cd136]
[billing@bfdx]$ cc test.cpp -o a1.out
[billing@bfdx]$ g++ test.cpp -o a2.out
[billing@bfdx]$ ls -l
total 36
-rwxr-xr-x    1 billing  users       13673 Aug  2 19:53 a1.out*
-rwxr-xr-x    1 billing  users       13923 Aug  2 19:53 a2.out*
-rw-r--r--    1 billing  users          59 Aug  2 19:53 test.cpp
[billing@bfdx]$ ldd *.out
a1.out:
        libc.so.6 => /lib/i686/libc.so.6 (0x40018000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
a2.out:
        libstdc++-libc6.2-2.so.3 => /usr/lib/libstdc++-libc6.2-2.so.3 (0x40018000)
        libm.so.6 => /lib/i686/libm.so.6 (0x4005a000)
        libc.so.6 => /lib/i686/libc.so.6 (0x4007d000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
[/code:1:7eec1cd136]

 蓝色键盘 回复于:2003-08-02 20:01:18
感谢你的测试结果,在Linuix上,差不多g++要比cc大些。
如上蜗牛兄弟测试了动态库的情况。

现在你把动态库mv为另外一个文件名称,让连接程序连接静态库,看看测试结果。让大家澄清这个问题。

 qjlemon 回复于:2003-08-02 20:14:47
老大可别吓我哟,改了那个动态库会不会死菜呀?偶不敢  
那天在AIX上就改过一个目录,结果马上连ls都没法用了,吓得我一身冷汗呀!好在急中生智。。。
测了,令人吃惊,竟然生成了完全一样的执行程序:
[code:1:f8bef7e434]

[billing@bfdx]$ cc -static -o a1.out test.cpp
[billing@bfdx]$ g++ -static -o a2.out test.cpp
[billing@bfdx]$ ls -l
total 3308
-rwxr-xr-x    1 billing  users     1686043 Aug  2 20:15 a1.out*
-rwxr-xr-x    1 billing  users     1686043 Aug  2 20:15 a2.out*
-rw-r--r--    1 billing  users          59 Aug  2 19:53 test.cpp
[billing@bfdx]$ ldd a*
a1.out:
        not a dynamic executable
a2.out:
        not a dynamic executable
[billing@bfdx]$ cmp a1.out a2.out
[/code:1:f8bef7e434]

 蓝色键盘 回复于:2003-08-02 20:19:59
在测试这个情况之前,请备份你的动态库文件,更改为你自己识辨的名字。偶那个帖子给你建议了呀,呵呵

在编译连接静态库的过程中,请删除上次生成的可执行程序在编译。

 qjlemon 回复于:2003-08-02 20:26:28
我要再找台机子  这个是生产系统,不敢动libc

 蓝色键盘 回复于:2003-08-02 20:29:29
如果是生成环境,蜗牛你可要小心了。

呵呵

等你的结果ing....

 qjlemon 回复于:2003-08-02 20:35:30
今天怕是不用等了  
偶要找个BSD,在那上面偶放心 

 蓝色键盘 回复于:2003-08-02 20:36:36
好的, 蜗牛兄弟,我可不想坑害你呀。

保证安全了在测试吧。

 qjlemon 回复于:2003-08-02 20:37:57
[quote:16dc91a3a9="蓝色键盘"]我可不想坑害你呀。[/quote:16dc91a3a9]这说哪的话 

 蓝色键盘 回复于:2003-08-02 20:45:59
[quote:fbababbd05="qjlemon"]billing@bfdx]$ cc -static -o a1.out test.cpp 
[billing@bfdx]$ g++ -static -o a2.out test.cpp 
[billing@bfdx]$ ls -l 
total 3308 
-rwxr-xr-x    1 billing  users     1686043 Aug  2 20:15 a1.out* 
-rwxr-xr-x    1 billing  users     1686043 Aug  2 20:15 a2.out* 
-rw-r--r--    1 billing  users          59 Aug  2 19:53 test.cpp 
[billing@bfdx]$ ldd a* 
a1.out: 
        not a dynamic executable 
a2.out: 
        not a dynamic executable 
[billing@bfdx]$ cmp a1.out a2.out 
[/quote:fbababbd05]     


静态库显然要比动态库大,现在是g++和cc编译的大小一样。下次测试最好注g++和cc编译程序的版本,这样便于分析。

 qjlemon 回复于:2003-08-02 20:50:26
[code:1:429f0d17c5]
[billing@bfdx]$ gcc -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.96/specs
gcc version 2.96 20000731 (Red Hat Linux 7.1 2.96-98)
[billing@bfdx]$ g++ -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.96/specs
gcc version 2.96 20000731 (Red Hat Linux 7.1 2.96-98)
[/code:1:429f0d17c5]

 蓝色键盘 回复于:2003-08-02 20:56:46
偶的意思是你在BSD或者其它的系统最好也注明版本。呵呵

 stevenyi 回复于:2003-08-02 21:26:39
[quote:655d44e976="qjlemon"]那天在AIX上就改过一个目录,结果马上连ls都没法用了,吓得我一身冷汗呀!好在急中生智。。。 [/quote:655d44e976]    

请教一下,你生出了什么智了? 我也犯过同样的错误,结果只好重新安装AIX

 蓝色键盘 回复于:2003-08-02 21:35:59
更改的时候注意符号连接和权限,而且做好备份,否则可能导致不可用。

 qjlemon 回复于:2003-08-02 21:39:45
这个得要有一点运气,就是你还没有退出root shell,我在AIX版贴过了,比如把目录由aa改成了aa.bak,这时就来个export LIBPATH=aa.bak,再把aa.bak mv回来就可以了

 stevenyi 回复于:2003-08-02 21:45:10
多谢! 又学了一招

 蓝色键盘 回复于:2003-08-02 21:47:37
蜗牛兄弟可是经验不少。

stevenyi怎么很久没有看到你了?

 stevenyi 回复于:2003-08-02 22:10:09
我很少发言的,呵呵     

[quote:8196c97a62="蓝色键盘"]蜗牛兄弟可是经验不少。

stevenyi怎么很久没有看到你了?[/quote:8196c97a62]

 蓝色键盘 回复于:2003-08-02 22:11:11
偶在unix高级技术版常看到你。

有时间多来这里转转。这里的兄弟需要你这样的高手帮忙。

 stevenyi 回复于:2003-08-02 22:14:43
说我吗? 我可不敢称高手
不过最进在玩FreeBSD,所以来c/c++版少了些

 蓝色键盘 回复于:2003-08-02 22:16:43
每个人都有可以学习的地方。

对于我不懂的,就需要向你请教。

 qjlemon 回复于:2003-08-02 23:48:41
刚才在一个BSD上测了一下,FreeBSD 4.7 mini版,干净的系统,cc、g++都是系统自带的2.95版。
test.cpp
[code:1:a0aee8dea2]
#include <stdio.h>
main()
{
}
[/code:1:a0aee8dea2]
由于没有联网,不太好把结果粘上来,观察了一下,和上面的结果基本是一样的,不过有意思的是,用g++编译的程序用到了/usr/lib/libstdc++.so,如果把这个动态库改个目录,重新用g++编译以后生成的文件就不再用libstdc++.so,并且变得小了一些!但是比用cc编译出来的仍然大了一点。
这和预期的结果是不同的,本以为把libstdc++.so藏起来以后会静态链接libstdc++.a,但看起来。。。这个到底有没有静态链接libstdc++.a呢?上面这个测试程序太简单了,无法说明问题。
至于libc.so,改了名字以后cc或g++根本无法工作,无从测起,可能得另想办法。。。
大家谁要试这个的话最好在FreeBSD里试,并非因为偶偏好BSD,而是因为在FreeBSD里/bin里的重要命令如ls和mv是静态链接的,不需要用到任何共享库

 蓝色键盘 回复于:2003-08-03 00:32:40
在LD_LIBRARY_PATH加上这个libc的静态库的路径,并且让其生效,试试,呵呵。

重新用g++编译以后生成的文件就不再用libstdc++.so,并且变得小了一些!但是比用cc编译出来的仍然大了一点。 

这个属于合理的。

现在可以对照g++和cc对于动态和静态两种方式的大小,然后strip后在比较一下。

 qjlemon 回复于:2003-08-03 08:04:30
用LD_LIBRARY_PATH设了以后g++仍不能工作,看来有必要编译一个静态链接的g++ ?
我又做了几个实验,由于观察到对g++编译的程序额外用到了libstdc++.so和libm.so,我把它们都藏起来,这样用cc和g++都会生成完全一样的执行程序,另外用-static选项进行编译,也生成完全一样的程序,再进行strip,执行程序的大小按照预期,变得小了很多。
另外如果包含的不是stdio.h而是iostream.h,生成的程序会大很多。
通过这些实验,我严重怀疑cc和g++用了同一个代码生成器,只是在链接的时候有所不同,如果条件允许,g++会自动加上libstdc++.so和libm.so,或许在别的平台上会加上libcrypt.so之类
关于cc和g++在这方面的对比是否可以算是得出了结论?
我想更深入的验证也可以做一做,比如生成汇编代码、生成.o文件比一比大小、让编译器把自己的详细操作都显示出来,还有编译一个静态链接的cc和g++,再来试验把libc.so也藏起来。。。好多喔  有兴趣和有时间的朋友试一下?再次推荐在FreeBSD上试。

 admirer 回复于:2003-08-03 09:16:43
看见你们讨论得如此热闹,我好羡慕呀!
可是,本人水平太差,看见C++好怕怕!

 qjlemon 回复于:2003-08-03 11:20:28
呵呵偶来个终结版。。
cc的详细过程:
[code:1:d2f7ed8c9b]
[lemon@bsd]$ cc -v test.cpp
Using builtin specs.
gcc version 2.95.3 20010315 (release) [FreeBSD]
 /usr/libexec/cpp0 -lang-c++ -v -D__GNUC__=2 -D__GNUG__=2 -D__GNUC_MINOR__=95 -D__cplusplus -Di386 -D__FreeBSD__=4 -D__FreeBSD_cc_version=440000 -Dunix -D__i386__ -D__FreeBSD__=4 -D__FreeBSD_cc_version=440000 -D__unix__ -D__i386 -D__unix -Acpu(i386) -Amachine(i386) -Asystem(unix) -Asystem(FreeBSD) -D__EXCEPTIONS -Acpu(i386) -Amachine(i386) -Di386 -D__i386 -D__i386__ -D__ELF__ test.cpp /tmp/ccDLmMO1.ii
GNU CPP version 2.95.3 20010315 (release) [FreeBSD] (i386 FreeBSD/ELF)
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/g++
 /usr/include
 /usr/include
End of search list.
The following default directories have been omitted from the search path:
End of omitted list.
 /usr/libexec/cc1plus /tmp/ccDLmMO1.ii -quiet -dumpbase test.cc -version -o /tmp/cckbiN8A.s
GNU C++ version 2.95.3 20010315 (release) [FreeBSD] (i386-unknown-freebsd) compiled by GNU C version 2.95.3 20010315 (release) [FreeBSD].
 /usr/libexec/elf/as -v -o /tmp/ccGCij1s.o /tmp/cckbiN8A.s
GNU assembler version 2.11.2 20010719 [FreeBSD] (i386-unknown-freebsd4) using BFD version 2.11.2 20010719 [FreeBSD]
 /usr/libexec/elf/ld -m elf_i386 -dynamic-linker /usr/libexec/ld-elf.so.1 /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtbegin.o -L/usr/libexec/elf -L/usr/libexec -L/usr/lib /tmp/ccGCij1s.o -lgcc -lc -lgcc /usr/lib/crtend.o /usr/lib/crtn.o
[/code:1:d2f7ed8c9b]
g++的详细过程:
[code:1:d2f7ed8c9b]
[lemon@bsd]$ rm a.out
[lemon@bsd]$ g++ -v test.cpp
Using builtin specs.
gcc version 2.95.3 20010315 (release) [FreeBSD]
 /usr/libexec/cpp0 -lang-c++ -v -D__GNUC__=2 -D__GNUG__=2 -D__GNUC_MINOR__=95 -D__cplusplus -Di386 -D__FreeBSD__=4 -D__FreeBSD_cc_version=440000 -Dunix -D__i386__ -D__FreeBSD__=4 -D__FreeBSD_cc_version=440000 -D__unix__ -D__i386 -D__unix -Acpu(i386) -Amachine(i386) -Asystem(unix) -Asystem(FreeBSD) -D__EXCEPTIONS -Acpu(i386) -Amachine(i386) -Di386 -D__i386 -D__i386__ -D__ELF__ test.cpp /tmp/ccSmiXAt.ii
GNU CPP version 2.95.3 20010315 (release) [FreeBSD] (i386 FreeBSD/ELF)
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/g++
 /usr/include
 /usr/include
End of search list.
The following default directories have been omitted from the search path:
End of omitted list.
 /usr/libexec/cc1plus /tmp/ccSmiXAt.ii -quiet -dumpbase test.cc -version -o /tmp/cclRbRCe.s
GNU C++ version 2.95.3 20010315 (release) [FreeBSD] (i386-unknown-freebsd) compiled by GNU C version 2.95.3 20010315 (release) [FreeBSD].
 /usr/libexec/elf/as -v -o /tmp/ccuYGOYV.o /tmp/cclRbRCe.s
GNU assembler version 2.11.2 20010719 [FreeBSD] (i386-unknown-freebsd4) using BFD version 2.11.2 20010719 [FreeBSD]
 /usr/libexec/elf/ld -m elf_i386 -dynamic-linker /usr/libexec/ld-elf.so.1 /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtbegin.o -L/usr/libexec/elf -L/usr/libexec -L/usr/lib /tmp/ccuYGOYV.o -lstdc++ -lm -lgcc -lc -lgcc /usr/lib/crtend.o /usr/lib/crtn.o
[/code:1:d2f7ed8c9b]
前面都是一样的,只是在链接的时候g++多了一个
-lstdc++ -lm
注意看最后一步  
看起来cc和g++只是一个前端

 gadfly 回复于:2003-08-04 10:01:03
可以用ldd查看程序链接了哪些动态库。

 li2002 回复于:2003-08-04 15:29:23
偶回来看大家讨论得真热阿,又学了不少,谢谢各位高手!
还想问大家一下:那里有g++编译参数的详细说明呢,用google也没搜到多少详细的东东。

原文转自:http://www.ltesting.net

评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)