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

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


当前回答

我通常找没用的东西的方法是

确保构建系统正确地处理依赖项跟踪 设置第二个监视器,使用全屏终端窗口,运行重复构建并显示第一个满屏的输出。watch "make 2>&1"倾向于在Unix上做到这一点。 在整个源代码树上运行查找和替换操作,添加“//?”“在每一行的开头 通过删除相应行中的"//?"来修复编译器标记的第一个错误。 重复操作,直到没有错误。

这是一个有点漫长的过程,但确实能得到很好的结果。

其他回答

CppDepend是一个商业工具,它可以检测未使用的类型、方法和字段,以及做更多的事情。它适用于Windows和Linux(但目前不支持64位),并有两周的试用期。

免责声明:我不在那里工作,但我拥有这个工具的许可证(以及NDepend,它是。net代码的一个更强大的替代方案)。

对于那些好奇的人来说,这里有一个内置的(可定制的)检测死方法的规则示例,用CQLinq编写:

// <Name>Potentially dead Methods</Name>
warnif count > 0
// Filter procedure for methods that should'nt be considered as dead
let canMethodBeConsideredAsDeadProc = new Func<IMethod, bool>(
    m => !m.IsPublic &&       // Public methods might be used by client applications of your Projects.
         !m.IsEntryPoint &&            // Main() method is not used by-design.
         !m.IsClassConstructor &&      
         !m.IsVirtual &&               // Only check for non virtual method that are not seen as used in IL.
         !(m.IsConstructor &&          // Don't take account of protected ctor that might be call by a derived ctors.
           m.IsProtected) &&
         !m.IsGeneratedByCompiler
)

// Get methods unused
let methodsUnused = 
   from m in JustMyCode.Methods where 
   m.NbMethodsCallingMe == 0 && 
   canMethodBeConsideredAsDeadProc(m)
   select m

// Dead methods = methods used only by unused methods (recursive)
let deadMethodsMetric = methodsUnused.FillIterative(
   methods => // Unique loop, just to let a chance to build the hashset.
              from o in new[] { new object() }
              // Use a hashet to make Intersect calls much faster!
              let hashset = methods.ToHashSet()
              from m in codeBase.Application.Methods.UsedByAny(methods).Except(methods)
              where canMethodBeConsideredAsDeadProc(m) &&
                    // Select methods called only by methods already considered as dead
                    hashset.Intersect(m.MethodsCallingMe).Count() == m.NbMethodsCallingMe
              select m)

from m in JustMyCode.Methods.Intersect(deadMethodsMetric.DefinitionDomain)
select new { m, m.MethodsCallingMe, depth = deadMethodsMetric[m] }

你可以尝试使用Gimple Software的PC-lint/FlexeLint。它声称

找到未使用的宏,typedef, 类、成员、声明等。 贯穿整个项目

我曾用它进行静态分析,并发现它非常好,但我必须承认,我没有专门用它来查找死代码。

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

根据文档:

Warn whenever a variable is unused aside from its declaration, whenever a function is declared static but never defined, whenever a label is declared but not used, and whenever a statement computes a result that is explicitly not used.

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

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

This option is intended to warn when the compiler detects that at least a whole line of source code will never be executed, because some condition is never satisfied or because it is after a procedure that never returns.

我认为您正在寻找一个代码覆盖工具。代码覆盖工具将在代码运行时分析它,它将让您知道哪些代码行被执行了,执行了多少次,以及哪些代码没有执行。

您可以尝试使用这个开源代码覆盖工具:TestCocoon—用于C/ c++和c#的代码覆盖工具。

我不认为它可以自动完成。

即使使用代码覆盖工具,也需要提供足够的输入数据来运行。

可能是非常复杂和昂贵的静态分析工具,如Coverity的或LLVM编译器可能会有所帮助。

但我不确定,我更喜欢手动代码审查。

更新

嗯. .不过,仅删除未使用的变量和未使用的函数并不难。

更新

看了其他人的回答和评论后,我更加坚定地认为这是不可能的。

您必须了解代码以获得有意义的代码覆盖率度量,如果您知道大量的手动编辑将比准备/运行/检查覆盖率结果更快。