首先,我要创建一个小程序:
#include <gmpxx.h>
void function() {
//mpf_class num;
return;
}
int main() {}
请注意,我包含第三方库,但未使用其任何内容 我去编译程序:
$ g++ main.cpp -Wl,--as-needed -lgmp -lgmpxx
$ readelf -d a.out | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
即使我将两个额外的库链接到此程序,我也传递了标志--as-nedded
,它发现在运行时实际上并不需要这两个库。因此,readelf
向我们表明他们实际上没有联系。
(gcc
实际上将其他c和c ++库链接到除libc
之外的二进制文件,但--as-needed
标志发现那些文件也不需要。)
我在这里引用了库代码,但实际上并不需要它:
#include <gmpxx.h>
void function() {
mpf_class num;
return;
}
int main() {}
$ g++ main.cpp -Wl,--as-needed -lgmp -lgmpxx
$ readelf -d a.out | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libgmp.so.10]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
问题:
我假设未使用的函数被丢弃,并且不会成为二进制文件的一部分。假设编译器意识到&#34;函数&#34;代码是不需要的,并且可以抛弃它,为什么它还能意识到gmp
的链接也不再需要?
有趣的是,使用完全优化运行命令
$ g++ -Ofast main.cpp -Wl,--as-needed -lgmp -lgmpxx
$ readelf -d a.out | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libgmp.so.10]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
导致某些gcc的隐式链接库在由于gmp
包含而保留以前未经优化时被排除。
问题: 鉴于库代码永远不会被执行,编译器是否能够排除第三方库?
答案 0 :(得分:1)
如果编译器绝对确定某些代码不会被使用,则允许将其丢弃。如果是这样,则呼叫不会显示在对象中,并且库已被忽略。
在未调用的示例函数中,它默认为extern
,因此编译器无法知道它是否是从另一个文件调用的,并且不允许摆脱它。但是大多数编译器只是一次编译一个函数,并且很少进行函数内分析。所以我怀疑当前的编译器是否会编译该文件(使用static void function()
),请注意该函数未被调用,并将其删除。也许一个聪明的连接器(进行整个程序分析)会这样做,但我没有仔细看过它。