개발 중에 코드 중복을 감지하는 방법은 무엇입니까? [닫은]


79

우리는 상당히 큰 코드베이스, 400K LOC의 C ++를 가지고 있으며 코드 중복은 문제가됩니다. 중복 된 코드 블록을 효과적으로 감지 할 수있는 도구가 있습니까?

이상적으로는 개발자가 문제가있는 위치를 확인하기 위해 가끔 실행하는 것보다 개발 중에 사용할 수있는 것입니다. 이러한 도구를 CruiseControl과 통합하여 체크인 할 때마다 보고서를 제공 할 수 있다면 좋을 것입니다.

나는 얼마 전에 Duploc봤는데 , 좋은 그래프를 보여 주었지만 그것을 사용하려면 스몰 토크 환경이 필요하기 때문에 자동으로 실행하기가 다소 어렵습니다.

무료 도구도 좋지만 좋은 상용 도구가 있다면 나도 관심을 가질 것입니다.


3
누군가 붙여 넣기 버튼을 사용할 때마다 :-}
Ira Baxter

답변:


36

Simian 은 C ++ 프로젝트에서 중복 코드를 감지합니다.

업데이트 : Java, C #, C, COBOL, Ruby, JSP, ASP, HTML, XML, Visual Basic, Groovy 소스 코드 및 일반 텍스트 파일에서도 작동합니다.


겠습니까 원활 .mm 파일을 확인 유인원, AKA 오브젝티브 -c ++
rraallvv

1
@rraallvv Simian은 일반 텍스트 검사를 수행 할 수 있으므로 모든 언어에서 코드 중복을 감지 할 수 있습니다.
Catharz

2
상업적 용도로는 무료가 아닙니다.
Zitrax 2015 년

Linux의 디렉토리에서 기본 설정으로 실행하면 재귀 적으로 작동하지 않는 것 같습니다.
ZeroPhase

20

내가 사용했던 PMD의 복사 및 붙여 넣기 - 감지기를 다음과 같은 래퍼 스크립트를 사용하여 CruiseControl을로 통합 (클래스 패스의 PMD 병을 가지고해야합니다).

수표는 야간에 실행됩니다. 현재 변경 세트의 파일 만 나열하도록 출력을 제한하려면 몇 가지 사용자 정의 프로그래밍이 필요할 수 있습니다 (아이디어 : 변경된 파일 중 하나가 관련된 중복 항목 만 모두 확인하고 나열합니다. 변경 사항이 사용할 수 있으므로 모든 파일을 확인해야합니다. 변경되지 않은 파일의 일부 코드). XML 출력을 사용하고 결과를 구문 분석하여 수행 할 수 있어야합니다. 완료되면 해당 스크립트를 게시하는 것을 잊지 마십시오.)

우선 "텍스트"출력은 괜찮지 만 사용자 친화적 인 방식으로 결과를 표시하고 싶을 것입니다.이 경우 펄 스크립트를 사용하여 CPD의 "xml"출력에서 HTML 파일을 생성합니다. 크루즈의보고 jsp가있는 바람둥이에 게시하여 액세스 할 수 있습니다. 개발자는 거기에서 그들을 볼 수 있으며 더러운 해킹의 결과를 볼 수 있습니다. :)

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>


sourgeforge 페이지에서 최신 버전을 사용하십시오! 그들의 문서 페이지는 활발한 개발이있는 동안 2011 년의 버전을 제안합니다. 제 경우에는 버전 5.5가 홈페이지에 링크 된 버전 4.2보다 훨씬 잘 작동합니다.
FourtyTwo

더 이상 문서에 C ++ 지원에 대한 언급이 없습니다.
ZeroPhase

PMD의 중복 코드 페이지에 대한 최신 링크는 pmd.github.io/latest/pmd_userdocs_cpd.html#supported-languages입니다
Laurent S

6

duplo 는 Duploc에서 사용되는 알고리즘의 C 구현으로 보입니다. 컴파일 및 설치가 간단하고 옵션이 제한되어 있지만 기본적으로 작동하는 것처럼 보입니다.


거의 중복이 많은 레거시 코드 파일에서 시도해 보았고 완벽한 중복이 거의없는 최근 코드 파일과 비교했습니다. 레거시 파일은 완벽하다고 평가되었습니다. 새 파일이 불량으로 평가되었습니다.
Sebastian Mach

5

이 데비안 패키지는 다음 과 같은 작업을 수행하는 것 같습니다 .

추신 : 중복을 찾는 데 관련된 모든 도구에 대한 부채 태그 가 있어야합니다 . (하지만 무엇이라고 부를까요?)


완벽한 대답입니다. 패키지 similarity-tester에는 포괄적 인 man 페이지 man 1 sim가 있으며 즉시 사용 가능하며 설득력있는 결과를 생성합니다.
Joachim W


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 ++ 용을 포함하여 여러 클론 감지 실행 예제 보고서가 있습니다.

2014 년 2 월 편집 : 이제 모든 C ++ 14를 처리합니다.


1

CCFinderX 는 여러 프로그래밍 언어 (Java, C, C ++, COBOL, VB, C #)를 지원하는 무료 (사내 사용) 복제 코드 탐지기입니다.


이 링크에 감사드립니다. 나는 그것을 확실히 볼 것입니다. 더 좋은 점은 일본어 버전이 있다는 것입니다 (나를 제외한 프로젝트의 다른 모든 개발자는 일본어입니다)
David Dibben

1

"동일한"코드 조각을 찾는 것은 비교적 쉽습니다. 이미 이것을 수행하는 기존 도구가 있습니다 (다른 답변 참조).

때로는 좋은 일이고 때로는 그렇지 않습니다. 너무 세밀한 "수준"에서 수행하면 개발 시간이 단축 될 수 있습니다. 즉, 너무 많은 코드를 리팩토링하려고하면 목표를 잃게됩니다 (그리고 아마 이정표와 일정을 망칠 수 있습니다).

더 어려운 것은 동일한 작업을 수행하지만 적절한 문서 없이는 다른 (그러나 유사한) 입력 및 / 또는 알고리즘을 사용하는 여러 함수 / 방법을 찾는 것입니다.

동일한 작업을 수행하기 위해 두 가지 또는 다른 방법이 필요하고 프로그래머가 한 인스턴스를 수정하려고하지만 다른 인스턴스를 수정하는 것을 잊어 버리거나 (또는 ​​존재하는지 알지 못하는 경우) 소프트웨어에 대한 위험이 증가합니다.


3
... 실제적으로 두 코드 다르게 구현되면 동일한 작업을 수행 한다는 것을 감지 할 수 없습니다 . 방해가되는 튜링 기계가 있습니다.
Ira Baxter

1
"더 어려운 것은 동일한 작업을 수행하지만 적절한 문서 없이는 다른 (그러나 유사한) 입력 및 / 또는 알고리즘을 사용하는 여러 함수 / 방법을 찾는 것입니다." 권리. 그리고 그들이 똑같은 일을한다면, 그 이름이 왜 그 코드가 처음에 존재하는지 설명해야하기 때문에 같은 이름이어야합니다. 따라서 첫 번째 단계는 모든 기능 / 방법이 정확하게 이름이 지정되고 문서화되었는지 확인하는 것입니다. 이름이 그것이하는 일을 진정으로 설명한다면 유사성과 정체성이 금방 분명해질 것입니다.
MickeyfAgain_BeforeExitOfSO 2010

문제는 "같은 일을한다"오라클 (내가 중단하는 오라클보다 훨씬 더 강력하다고 생각하는)조차도 두 이름이 동일한 아이디어를 표현 (또는 표현하려는 의도)하는지 파악하는 데 도움이되지 않는다는 것입니다. (이 외에도, 오탐 (false positive)이 많이있을 경향이있다.)
SAMB



1

SourceMeter 도구를 사용하여 코드 중복을 감지 할 수 있습니다 . 명령 줄 도구 (컴파일러와 매우 유사)이므로 언급 한 CruiseControl 또는 Jenkins 와 같은 지속적인 통합 도구에 쉽게 통합 할 수 있습니다 .


0

또한이 유인원은Java, C #, C ++, C, Objective-C, JavaScript를 지원하는 .

Hudson 에서 지원합니다. (예 : CPD).

오픈 소스 프로젝트가 아니라면 Simian에 대한 비용지불 해야합니다 .


-3

TeamCity 에는 빌드 시스템의 일부로 손쉽게 실행할 수있는 .NET 및 Java 용 강력한 코드 복제 엔진이 있습니다.


.Net 또는 Java는 C ++가 아니므로 실행하기가 쉽지만 결실도 없습니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.