当GCC以优化方式编译代码的时候,它会执行Dead Code Elimiation(DCE), 就是把那些源代码中定义但是却从未调用到的函数从中间目标文件中去掉.(.o文件)
例如下面这段代码:
#include <stdio.h>
static void test() {
printf ("this code is never called.");
}
int main() {
printf("this is main function.");
return 0;
}
这里我们定义了一个static函数和一个main函数.按照C语言的约定,static 函数是只在当前模块可见, 非static函数则可被其它模块所包含.
然后我们通过检查使用和不使用DCE时,GCC的汇编输出来观察DCE的作用.
不使用DCE:
gcc -S -fno-builtin -fdump-ipa-cgraph test.c -o test.S
这里生成汇编结果说明了DCE的过程是在编译阶段已经完成, 命令中
-fdump-ipa-cgraph, 这是个调试输出选项,会生成一个.cgraph文件,我们后面会进一步查看这个文件.
查看test.S可以发现_test这个函数的定义出现在汇编代码中,
如果编译生成.o文件的话,使用nm工具可以看到中间目标文件中的符号定义中也存在test这个函数.
nm test.o
00000017 T _main
U _printf
00000000 t _test
00000017 T _main
U _printf
00000000 t _test
接下来打开DCE开关看看:
gcc -O -S -fno-builtin -fdump-ipa-cgraph test.c -o test.S
可以看到,test函数已经不在了.nm中也不见了_test符号.
00000000 T _main
U _printf
U _printf
随汇编过程,GCC还会生成一个.cgraph的文件,这里面记录了gcc移除函数过程.