我希望在代码库中找到未使用的函数-包括跨编译单元。我使用gcc作为我的编译器。
下面是一个例子:foo.c
(假设foo.h
适当):
void foo() {
....
}
void bar() {
....
}
main.c
:
#include <stdio.h>
#include "foo.h"
int main(void) {
bar();
return 0;
}
在本例中,我希望得到foo()
未被使用的警告。
有-Wunused-function
gcc选项:-Wunused-function
当静态函数被声明但未被定义或非内联静态函数未被使用时发出警告。此警告由-Wall启用。
但它只适用于静态函数--在上面的例子中它不会产生警告。
我也会接受工具/脚本/其他编译器的建议,这些工具/脚本/其他编译器可以为我做这件事--尽管如果可能的话,我更愿意坚持使用gcc
。
6条答案
按热度按时间ftf50wuq1#
Caolan Mc Namara,一个LibreOffice开发者,已经开发了一个小工具来检测LibreOffice源代码中的这类问题。他们有大约数千个函数和方法在LibreOffice中没有使用。他的工具是删除它们的关键因素。
它叫做callcatcher。它可以
收集定义的函数/方法并调用/引用减法
它直接作用于汇编器的输出,所以它只适用于x86和x86_64架构,它可以产生类似this的输出,你可以将它与传统的编译和链接gcc调用集成。
caulan同意它应该成为一个gcc插件。
egdjgwm82#
我知道你要求警告,并不喜欢使用gcc选项,但它真的很容易。
您可以使用链接器优化(--gc-sections)来删除应用程序中的死代码。
来自ld's手册页:
解释:
这个选项可以在进行部分链接时设置(使用选项-r启用)。在这种情况下,必须通过--entry或--undefined选项或链接器脚本中的"ENTRY"命令显式指定所保留符号的根。
wj8zmpe13#
首先,如果你想让这样的警告在程序范围内出现,你当然需要
-flto
标志,因为它应该在链接时解决,而不是在编译每个单元的时候。但是我不认为GCC提供这样的警告,即使是这样。那么,在一般情况下,我会理解提供它是不明智的(因为,例如,链接的
libc
可能有许多您的应用程序不需要的函数)。此外,应用程序可以使用dlsym
技巧来访问一个明显未调用的函数...然而,这是GCC插件或MELT扩展的一个很好的潜在用例示例,它将在某个地方注册每个调用事件,并在稍后的实用程序中查找所有未调用的函数。(但是为GCC编写插件或MELT扩展至少需要几天时间,因为您需要了解GCC的内部结构)。
您还可以使用分析技术来获取动态未使用(未调用)的函数。
欢迎通过电子邮件向我询问更多信息。
ego6inou4#
将gcc选项
-ffunction-sections
添加到编译中,将--gc-sections
和--print-gc-sections
添加到link命令中,如果通过gcc调用链接器,则使用-Wl,--gc-sections,--print-gc-sections
将它们传递给ld。这将去除未使用的目标代码,您说过您不需要这些代码。在这种情况下,生成所需的输出后,请删除
--gc-sections
。您没有询问如何识别未使用的数据,但要做到这一点,还需要在编译中添加
-fdata-sections
选项。u4vypkhs5#
我想
gprof
是最简单的解决方案,我编译了您提供的带有-pg
选项的示例程序,以便在运行a.out
时获得gmon.out
(gprof可以稍后使用),然后我终于运行了gprof -z a.out gmon.out | tee output.txt
。我可以在unused列表中找到你的函数foo
!iidoe调用0
次。-z
是应该与gprof
沿着使用的选项,用于跟踪未使用的例程。感谢this线程提供的相应指针!
PS:
gprof
抛出了大量其他未使用的库函数沿着您未使用的函数foo
。我真的不知道如何过滤这个:)fwzugrvs6#
Eclipse CDT确实有代码分析功能,您可以设置它来标记未使用的静态函数和未使用的函数声明(以及其他有用的功能)。正如已经说过的,只有链接器才能分辨出某个(非静态)函数没有在某个二进制文件中使用...