我怎么知道代码中的哪些部分从未使用过?
我有遗留的C ++代码,我应该从中删除未使用的代码。问题是代码库很大。
如何找出从未调用/从未使用过的代码?
没有找到相关结果
已邀请:
18 个回复
厦惫
(GCC,Clang)应该警告未使用的变量,Clang未使用的分析器甚至已经增加,以警告从未读过的变量(即使使用过)。
(较旧的海湾合作委员会,2010年被删除)应该警告从未访问的本地区块(它发生在早期返回或总是评估为真的条件) 没有我知道的选项来警告未使用的
块,因为编译器通常无法证明不会抛出任何异常。 对于第二种,它要困难得多。静态地,它需要整个程序分析,并且即使链接时间优化实际上可以去除死代码,实际上程序在执行时已经被大量转换,几乎不可能向用户传达有意义的信息。 因此有两种方法: 理论上是使用静态分析仪。一个软件,可以一次性检查整个代码,并找到所有流程。在实践中,我不知道任何可行的方法。 实用的是使用启发式:使用代码覆盖工具(在GNU链中它是
。请注意,在编译期间应该传递特定的标志,以使其正常工作)。您使用一组良好的输入(单元测试或非回归测试)运行代码覆盖率工具,死代码必须在未到达的代码中...所以您可以从这里开始。 如果您对该主题非常感兴趣,并且有时间和倾向自己实际制定工具,我建议使用Clang库来构建这样的工具。 使用Clang库获取AST(抽象语法树) 从入口点开始执行标记和扫描分析 因为Clang将为您解析代码并执行重载解析,所以您不必处理C ++语言规则,并且您将能够专注于手头的问题。 但是,这种技术无法识别未使用的虚拟覆盖,因为它们可能被您无法推理的第三方代码调用。
长拳
和
,然后在连接时使用
。链接器现在将列出可以删除的所有函数,因为它们从未被调用,并且所有从未引用过的全局变量。 (当然,您也可以跳过
部分并让链接器以静默方式删除这些函数,但将它们保留在源代码中。) 注意:这只会找到未使用的完整函数,它不会对函数内的死代码做任何事情。在实时函数中从死代码调用的函数也将被保留。 某些特定于C ++的功能也会导致问题,特别是: 虚拟功能。在不知道哪些子类存在以及哪些子类在运行时实际实例化的情况下,您无法知道最终程序中需要存在哪些虚函数。链接器没有足够的信息,所以它必须保持所有这些信息。 具有构造函数的全局变量及其构造函数。通常,链接器不能知道全局的构造函数没有副作用,因此它必须运行它。显然,这意味着全球本身也需要保留。 在这两种情况下,虚拟函数或全局变量构造函数使用的任何东西也必须保持不变。 另一个警告是,如果您正在构建共享库,GCC中的默认设置将导出共享库中的每个函数,从而导致它就链接器而言“被使用”。要解决此问题,您需要将默认值设置为隐藏符号而不是导出(使用例如
),然后显式选择需要导出的导出函数。
哩翔购
根据文件: 每当变量未使用时发出警告 除了宣言,无论何时 函数声明为static但是 从未定义,只要标签是 声明但未使用,并且每当a 语句计算结果 明确没有使用。 http://docs.freebsd.org/info/gcc/gcc.info.Warning_Options.html 编辑:这是其他有用的旗帜
根据文件: 此选项用于在编译器检测到至少一行源代码永远不会被执行时发出警告,因为某些条件永远不会得到满足,或者因为它位于永不返回的过程之后。 更新:我在遗留的C / C ++项目中发现了类似的主题死代码检测
驮帽俺篮号
掏得透垦滩
正如维基百科正确指出的那样,一个聪明的编译器可能能够捕获这样的东西。但考虑修改:
编译器会抓住这个吗?也许。但要做到这一点,它需要做的不仅仅是针对恒定的标量值运行
。它必须弄清楚
总是一个整数(简单),然后理解整数集(硬)的数学范围
。一个非常复杂的编译器可能能够为
函数或math.h中的每个函数执行此操作,或者为其可以找出其域的任何固定输入函数执行此操作。这变得非常非常复杂,复杂性基本上是无限的。您可以继续为编译器添加复杂的层次,但总会有一种方法可以隐藏某些代码,这些代码对于任何给定的输入集都是无法访问的。 然后有输入集,根本不会输入。输入在现实生活中没有任何意义,或被其他地方的验证逻辑阻止。编译器无法知道这些。 最终的结果是,虽然其他人提到的软件工具非常有用,但你永远不会知道你抓住了一切,除非你之后手动完成代码。即便如此,你永远不会确定你没有错过任何东西。 唯一真正的解决方案,恕我直言,要尽可能保持警惕,使用自动化,重构你可以,并不断寻找改进代码的方法。当然,无论如何都要做到这一点是个好主意。
泻伴墓荒
涸坍饺
结乳
倾向于在Unix上做这个技巧。 在整个源树上运行查找和替换操作,在每行的开头添加“//?” 修复编译器标记的第一个错误,删除“//?”在相应的行中。 重复,直到没有错误。 这是一个有点冗长的过程,但它确实给出了很好的结果。
捕暑句簿姓
味芯憨
,这是一个C / C ++程序分析工具,它是
套件的一部分,它还包含检查内存泄漏和其他内存错误的工具(您应该使用它们) )。它分析程序的运行实例,并生成有关其调用图的数据,以及调用图上节点的性能成本。它通常用于性能分析,但它也为您的应用程序生成一个调用图,因此您可以查看调用的函数以及调用者。 这显然是对页面上其他地方提到的静态方法的补充,它只对消除完全未使用的类,方法和函数有帮助 - 它无助于在实际调用的方法中找到死代码。
宠封钞轰
物崎巩
悸翠疮武昏
冉案
寇剩
蕉衫
bab
淘圃跺枯替
http://docs.freebsd.org/info/gcc/gcc.info.Warning_Options.html 编辑:这是其他有用的标志 - 无法访问的代码根据文档: