我有遗留的C++代码,我应该从中删除未使用的代码.问题是代码库很大.
如何找出从未调用/从未使用过的代码?
我需要严格优化可执行文件的大小(ARM开发),我注意到在我当前的构建方案(gcc+ ld)中,未使用的符号不会被剥离.
的用法arm-strip --strip-unneeded为生成的可执行文件/库不改变可执行文件的输出大小(我不知道为什么,也许它根本不能).
修改我的构建管道的方式是什么(如果存在),以便从结果文件中删除未使用的符号?
我甚至都不会想到这一点,但我当前的嵌入式环境并不是非常"强大",甚至500K可以节省2M非常好的加载性能.
更新:
不幸的是,gcc我使用的当前版本没有-dead-strip选项,并且-ffunction-sections... + --gc-sectionsfor ld不会对结果输出产生任何显着差异.
我很震惊,这甚至成了问题,因为我确信gcc + ld应该自动删除未使用的符号(为什么他们甚至要保留它们?).
请考虑以下代码,该代码具有无法访问的无法访问undefinedFunction.
void undefinedFunction();
template <bool b = false>
void foo()
{
static_assert(b == false);
if (b)
undefinedFunction();
}
int main()
{
foo();
}
Run Code Online (Sandbox Code Playgroud)
GCC在没有投诉的情况下编译和链接.有了static_assert,很难看出编译器如何做出不同的事情,但标准对此有什么要说的吗?如果static_assert删除怎么办?编译器是否有义务删除分支,或者它实际上是否会发出一条无法访问的调用指令,这会导致链接器抱怨?
说我有一个功能
void do_something() {
//....
#ifdef FEATURE_X
feature_x();
#endif
//....
}
Run Code Online (Sandbox Code Playgroud)
我可以编译并运行它没有任何问题; 如果我想要我可以通过的功能-D FEATURE_X,它的工作原理.
但是,如果我想do_something放入另一个文件(并且每次我决定更改选项时也不必重新编译该文件)该怎么办?如果它在同一个文件中,我会认为
const int FEATURE_X=0;
void do_something() {
//....
if(FEATURE_X) {
feature_x();
}
//....
}
Run Code Online (Sandbox Code Playgroud)
将正确使用死代码消除,取消呼叫.如果我把它放在另一个文件中,没有LTO,
extern const int FEATURE_X;
void do_something() {
//....
if(FEATURE_X) {
feature_x();
}
//....
}
Run Code Online (Sandbox Code Playgroud)
它不会删除代码(它无法知道).因此,在启用链接时优化的情况下,编译器是否可以检测FEATURE_X链接时的值,确定是否使用了代码,并在适当的情况下将其删除?