考虑以下示例
g++ a.o b.o c.o -o prog
如果c.o
没有向prog
提供任何可执行代码,在任何其他文件中对c.o
没有依赖关系,那么GCC是否还包括c.o
中的prog
内容?
换句话说,除了编译时间之外,还有什么(如果有的话)将不必要的文件编译成可执行文件的负面后果?
提前致谢;干杯!
答案 0 :(得分:5)
除了您的可执行文件可能不必要地大,否则没有任何负面后果。链接器可能会为您删除未使用的代码,这会缩减内容。您可以在输出可执行文件上使用某种对象查看工具(otool
,objdump
,nm
等),以查看您的程序中是否包含额外符号。
我正在使用Mac,所以如果您使用标准的gcc工具集会有一些差异,但这是一个例子:
$ make
gcc -o app main.c file2.c
gcc -Wl,-dead_strip -o app_strip main.c file2.c
$ ls -l app*
-rwxr-xr-x 1 carl staff 8744 Feb 6 20:05 app
-rwxr-xr-x 1 carl staff 8704 Feb 6 20:05 app_strip
我认为在非Apple gcc世界中,您会在我的示例中传递-Wl,--gc-sections
而不是-Wl,-dead_strip
。您可以看到的两个可执行文件的大小差异是由于剥离了额外的功能:
$ nm app | cut -c 20- > app.txt
$ nm app_strip | cut -c 20- > app_strip.txt
$ diff app.txt app_strip.txt
8d7
< _function2
答案 1 :(得分:3)
llvm
可以消除链接步骤中的死代码。它使用特殊链接器llvm-ld
。
此外,使用-fwhole
或-ipo
(英特尔)将有助于消除死亡符号。
答案 2 :(得分:2)
我刚试了一些我正在使用的C代码 - 我在一个对象中链接,该对象包含一个尚未在程序中的任何其他位置使用的方法。代码包含在生成的可执行文件中,通过对elf文件运行nm
进行检查,并观察方法T确实存在,即使使用-O2和-O3也是如此。
答案 3 :(得分:1)
是的,GCC将包含所有目标文件。使用最新的编译器(开发版本4.5.0),您可以使用-flto
(链接时优化)来执行此操作。