我有遗留的c++代码,我应该删除不使用的代码。问题是代码库很大。

我如何才能知道哪些代码从未被调用/从未被使用?


当前回答

如果你使用g++,你可以使用这个标志-Wunused

根据文档:

每当变量未使用时发出警告 除了它的声明,无论何时 函数被声明为静态的,但是 从来没有定义,每当一个标签 声明但未使用,并且每当a 语句计算的结果为 明确没有使用。

http://docs.freebsd.org/info/gcc/gcc.info.Warning_Options.html

编辑:这里是另一个有用的标志-Wunreachable-code 根据文档:

此选项用于在编译器检测到至少一整行源代码永远不会执行时发出警告,因为某些条件永远不会满足,或者因为它在一个永远不会返回的过程之后。

更新:我在遗留的C/ c++项目中发现了类似的主题死代码检测

其他回答

一种方法是使用调试器和编译器特性,在编译过程中消除未使用的机器代码。

一旦某些机器代码被删除,调试器就不会让你在相应的源代码行上添加断点。因此,您将断点放置在任何地方,并启动程序并检查断点——那些处于“此源未加载代码”状态的断点对应于已消除的代码——要么该代码从未被调用,要么已内联,您必须执行一些最小分析,以找出这两者中哪一个发生了。

至少这是它在Visual Studio中的工作方式,我猜其他工具集也可以做到这一点。

这需要做很多工作,但我认为比手动分析所有代码要快。

我自己没有使用过cppcheck,但它声称可以找到未使用的函数。这也许不能完全解决问题,但可能是个开始。

我有个朋友今天问了我这个问题,我看了看一些有前途的Clang开发,例如ASTMatchers和Static Analyzer,它们可能在编译过程中有足够的可见性来确定死代码部分,但后来我发现了这个:

https://blog.flameeyes.eu/2008/01/today-how-to-identify-unused-exported-functions-and-variables

它几乎完整地描述了如何使用一些GCC标志,这些标志似乎是为了识别未引用的符号而设计的!

GNU链接器有一个——cref选项,用于生成交叉引用信息。你可以通过-Wl,——cref从gcc命令行传递它。

例如,假设foo。O定义了一个符号foo_sym,也在bar.o中使用。然后在输出中你会看到:

foo_sym                            foo.o
                                   bar.o

如果foo_sym限制为foo。O,那么你不会看到任何额外的目标文件;后面会跟着另一个符号:

foo_sym                            foo.o
force_flag                         options.o

现在,从这里我们不知道是否使用了foo_sym。它只是一个候选:我们知道它是在一个文件中定义的,而没有在其他任何文件中使用。Foo_sym可以在foo中定义。O和用于那里。

那么,你该怎么处理这些信息呢

执行一些文本修改,以识别限制在一个目标文件中的这些符号,生成候选列表。 进入源代码,给每个候选对象提供带有静态的内部链接,就像它应该有的那样。 重新编译源代码。 现在,对于那些真正未使用的符号,编译器将能够警告,为你精确定位它们;你可以删除它们。

当然,我忽略了其中一些符号是故意不使用的可能性,因为它们是为动态链接而导出的(即使在链接可执行文件时也可能出现这种情况);这是一种更微妙的情况,你必须了解并明智地处理。

这取决于创建应用程序时使用的平台。

例如,如果你使用Visual Studio,你可以使用像. net ANTS Profiler这样的工具来解析和分析你的代码。通过这种方式,您应该很快知道实际使用了代码的哪一部分。Eclipse也有等效的插件。

否则,如果您需要知道最终用户实际使用了应用程序的哪些功能,并且您可以轻松地发布应用程序,则可以使用日志文件进行审计。

对于每个主要函数,您可以跟踪它的使用情况,并在几天/一周后获取日志文件,并查看它。