如何在开发过程中检测代码重复?

时间:2008-10-10 14:34:27

标签: c++ code-duplication

我们有一个相当大的代码库,400K的C ++ LOC,并且代码重复是一个问题。有没有可以有效检测重复代码块的工具?

理想情况下,这将是开发人员在开发过程中可以使用的东西,而不是偶尔运行以查看问题所在。如果我们能够将这样的工具与CruiseControl集成在每次签入后提供报告,那也很好。

前段时间我看过Duploc,它显示了一个不错的图表,但需要一个小型的环境来使用它,这使得自动运行它相当困难。

免费工具会很好,但如果有一些好的商业工具我也会感兴趣。

13 个答案:

答案 0 :(得分:35)

Simian检测到C ++项目中的重复代码。

更新:还适用于Java,C#,C,COBOL,Ruby,JSP,ASP,HTML,XML,Visual Basic,Groovy源代码甚至纯文本文件

答案 1 :(得分:19)

我使用PMD's Copy-and-Paste-Detector并使用以下包装脚本将其集成到CruiseControl中(确保在类路径中有pmd jar)。

我们的检查每晚进行一次。如果您希望将输出限制为仅列出当前更改集中的文件,则可能需要一些自定义编程(想法:检查所有并仅列出其中包含其中一个已更改文件的重复项。您必须检查所有文件,因为更改可能会使用来自未更改文件的一些代码)。应该可以通过使用XML输出和解析结果来实现。不要忘记在完成后发布该脚本;)

对于初学者来说,“Text”输出应该没问题,但是你需要以用户友好的方式显示结果,为此我使用perl脚本从CPD的“xml”输出生成HTML文件。可以通过将它们发布到巡航报告jsp所在的tomcat来访问它们。开发人员可以从那里查看它们并查看其脏黑客的结果:)

它在150个KLoc代码上运行得非常快,不到2秒(空行和注释未计入该数字)。

<强> duplicatecheck.xml

<project name="duplicatecheck" default="cpd">

<property name="files.dir" value="dir containing your sources"/>
<property name="output.dir" value="dir containing results for publishing"/>

<target name="cpd">
    <taskdef name="cpd" classname="net.sourceforge.pmd.cpd.CPDTask"/>
    <cpd minimumTokenCount="100" 
         language="cpp" 
         outputFile="${output.dir}/duplicates.txt"
         ignoreLiterals="false"
         ignoreIdentifiers="false"
         format="text">
        <fileset dir="${files.dir}/">
            <include name="**/*.h"/>
            <include name="**/*.cpp"/>
                <!-- exclude third-party stuff -->
            <exclude name="boost/"/>
            <exclude name="cppunit/"/>
        </fileset>
    </cpd>
</target>

答案 2 :(得分:6)

duplo似乎是Duploc中使用的算法的C实现。编译和安装很简单,虽然选项有限,但它似乎或多或少都是开箱即用的。

答案 3 :(得分:4)

查看PMD project

我从未使用过它,但一直都想这样做。

答案 4 :(得分:3)

这些Debian软件包似乎沿着以下几行

P.S。所有与查找[near]重复相关的工具都应该有一个debtags标签。 (但它会被称为什么?)

答案 5 :(得分:2)

好吧,您可以在源上运行克隆检测器 代码库每晚。

许多克隆探测器通过比较源线来工作, 并且只能找到确切的重复代码。

上面的CCFinder通过比较语言来工作 令牌,所以它对白色空间不敏感 变化。它可以检测变种克隆 如果只有单个令牌,则为原始代码 改变(例如,将变量X改为Y) 克隆)。

理想情况下,你想要的是上述,但能力 找到克隆在哪里 允许变化相对任意, 例如,用表达式,语句替换变量 通过块等

我们的CloneDR克隆检测器适用于Java,C#,C ++,COBOL,VB.net,VB6,Fortran和各种 其他语言可以在以下位置看到: http://www.semdesigns.com/Products/Clone/index.html

除了能够处理多种语言外,CloneDR引擎还能够处理各种输入编码样式,包括ASCII,ISO-8859-1,UTF8,UTF16,EBCDIC,多种Microsoft编码,以及(日语) )Shift-JIS。

该站点有几个克隆检测运行示例报告,包括一个用于C ++的报告。

EDIT 2014年2月:现在处理所有C ++ 14。

答案 6 :(得分:1)

CCFinderX是一个免费的(供内部使用)克隆代码检测器,支持多种编程语言(Java,C,C ++,COBOL,VB,C#)。

答案 7 :(得分:1)

查找“相同”代码片段相对容易,现有工具已经执行此操作(请参阅其他答案)。

有时它是好事,有时它不是;如果在太精细的“水平”下完成,它可能会缩短开发时间;即试图重构这么多代码,你就会失去目标(可能会破坏你的里程碑和时间表)。

更难的是找到多个功能/方法,这些功能/方法在没有适当文档的情况下使用不同(但相似)的输入和/或算法执行相同的操作。

如果您必须使用两种或两种不同的方法来执行相同的操作,并且程序员尝试修复一个实例但忘记(或者不知道它们存在)来修复其他实例,则会增加软件的风险。 / p>

答案 8 :(得分:1)

相同(http://sourceforge.net/projects/same/)非常简单,但它适用于文本行而不是令牌,如果您使用的语言不受其中一个较高级别的克隆查找器支持,则此功能很有用。

答案 9 :(得分:1)

ConQAT是一个支持C ++代码分析的好工具。可以找到忽略空格的重复项。拥有非常方便的gui和控制台界面。 由于它的灵活性,它不容易设置。我找到了this blog post very useful for setting up c++ project

答案 10 :(得分:1)

您可以使用我们的SourceMeter工具来检测代码重复。它是一个命令行工具(非常类似于编译器),因此您可以轻松地集成到持续集成工具中,例如您提到的CruiseControlJenkins

答案 11 :(得分:0)

还有Simian支持Java,C#,C ++,C,Objective-C,JavaScript ......

它受到 Hudson (如CPD)的支持。

除非你是一个开源项目,否则你必须为Simian付

答案 12 :(得分:-3)

TeamCity有一个强大的.NET和Java代码复制引擎,可以毫不费力地作为构建系统的一部分运行。