2008-10-10 3 views
66

У нас есть довольно большая база кода, 400K LOC на C++, а дублирование кода - это что-то вроде проблемы. Существуют ли какие-либо инструменты, которые могут эффективно обнаруживать дублированные блоки кода?Как обнаружить дублирование кода во время разработки?

В идеале это было бы тем, что разработчики могли бы использовать во время разработки, а не просто запускать время от времени, чтобы увидеть, где проблемы. Было бы неплохо также, если бы мы могли интегрировать такой инструмент с CruiseControl, чтобы дать отчет после каждой проверки.

Я взглянул на Duploc некоторое время назад, он показал хороший график, но для этого требуется небольшая окружающая среда , что делает запуск его автоматически довольно сложным.

Бесплатные инструменты были бы хороши, но если есть хорошие коммерческие инструменты, мне также было бы интересно.

+3

Всякий раз, когда кто-то использует кнопку вставки: -} – 2009-08-23 06:15:37

+0

Связанный вопрос - http://stackoverflow.com/questions/2490884/why-is-copy-and-paste-of-code-dangerous – Oded 2010-07-25 17:47:12

ответ

33

Simian обнаруживает дублирующий код в проектах на С ++.

Update: Также работает с Java, C#, C, COBOL, Ruby, JSP, ASP, HTML, XML, Visual Basic, Groovy исходный код и даже текстовые файлы

+0

будет simian проверять без проблем .mm файлы, AKA ObjectiveC++ – rraallvv 2013-03-23 05:09:30

+1

@rraallvv Simian может выполнять простые проверки текста, поэтому он может обнаруживать дублирование кода на любом языке. – Catharz 2013-07-11 06:34:27

+2

Обратите внимание, что это не бесплатно для коммерческого использования. – Zitrax 2015-09-15 12:03:01

5

Посмотрите на PMD project.

Я никогда не использовал его, но всегда хотел.

+0

Я думал, что PMD предназначен только для Java, но теперь я вижу, что CPD (который является частью PMD) также может использоваться для C++. – 2008-10-10 14:49:40

1

CCFinderX является бесплатным (для собственного использования) клонированным детектором кода, который поддерживает несколько языков программирования (Java, C, C++, COBOL, VB, C#).

+0

Спасибо за эту ссылку. Я обязательно посмотрю на это. Еще лучше то, что есть японская версия (все остальные разработчики проекта, кроме меня, - японцы) – 2008-10-11 06:14:23

-3

TeamCity имеет мощный механизм дублирования кода для .NET и java, который может легко запускаться как часть вашей системы сборки.

+0

Ни .NET, ни Java не являются C++, поэтому, хотя это может быть легко запускаться, это также бесплодно. – Tom 2010-03-07 01:55:17

18

Я использовал PMD's Copy-and-Paste-Detector и интегрировал его в CruiseControl, используя следующий скрипт-оболочку (обязательно, чтобы jpmd-файл в пути к классам).

Наша проверка работает ночью. Если вы хотите ограничить вывод списком только файлов из текущего набора изменений, вам может понадобиться какое-то пользовательское программирование (идея: проверьте все и перечислите только дубликаты, в которых задействован один из измененных файлов. Вы должны проверить все файлы, потому что изменение может использовать некоторый код из неизменяемого файла). Должно быть выполнимо с помощью вывода XML и анализа результата. Не забудьте опубликовать этот сценарий, когда это будет сделано;)

Для начала вывод «Текст» должен быть в порядке, но вы хотите отображать результаты удобным для пользователя способом, для которого я использую скрипт perl для генерации HTML-файлов из «xml» вывода CPD. Они доступны, отправляя их в tomcat, где находится отчет JSP о круизе. Разработчики могут просматривать их оттуда и видеть результаты их грязного взлома :)

Он работает довольно быстро, менее 2 секунд на 150 KLoc-код (пустые строки и комментарии не учитываются в этом номере).

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> 

1

Поиск "идентичный" фрагменты кода относительно легко, есть существующий инструмент, который уже делает это (см других ответов).

Иногда это хорошая вещь, иногда это не так; он может прогнать время разработки, если сделать его на слишком тонком «уровне»; то естьпытаясь реорганизовать так много кода, вы потеряете свою цель (и, вероятно, расстройте свои вехи и графики).

Что сложнее найти несколько функций/методов, которые выполняют одно и то же, но с разными (но похожими) входами и/или алгоритмом без надлежащей документации.

Если у вас есть два или несколько способов сделать то же самое, и программист попытается исправить один экземпляр, но забыть (или не знает, что они существуют), чтобы исправить другие, вы увеличите риск для своего программного обеспечения.

6

duplo представляется реализацией C алгоритма, используемого в Duploc. Его легко компилировать и устанавливать, и, хотя параметры ограничены, кажется, что более или менее работает из коробки.

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 Feb 2014: теперь обрабатывает все C++ 14.

1

То же самое (http://sourceforge.net/projects/same/) очень простое, но оно работает на текстовых строках вместо токенов, что полезно, если вы используете язык, который не поддерживается одним из искателей поиска fancier.

0

Существует также Simian, который поддерживает Java, C#, C++, C, Objective-C, JavaScript ...

Это поддерживается Хадсон (как ДСП).

Если вы не являетесь проектом с открытым исходным кодом, вы должны оплатить для Simian.

2

Для моей ссылки в будущем эти пакеты Debian, кажется, делают что-то вдоль этих линий:

Я мог бы поклясться, что у меня был другой пакет (ы), установленный может быть еще более актуальным, но я не могу найти их в данный момент. (Вот почему я перечисляю свои результаты здесь в этот раз: чтобы дать мне возможность снова найти их!)

P.S. Кажется, что должен быть тег debtags для всех инструментов, связанных с поиском [ближнего] дублирования. (Но что бы это называется?)

1

ConQAT - отличный инструмент, который поддерживает анализ кода на C++. Можно найти дубликаты, игнорируя пробелы. Имеет полные удобные интерфейсы gui и console. Из-за его гибкости его нелегко настроить. Я нашел this blog post very useful for setting up c++ project.

1

Вы можете использовать наш инструмент SourceMeter для обнаружения дубликата кода. Это инструмент командной строки (очень похожий на компиляторы), поэтому вы можете легко интегрироваться в инструменты непрерывной интеграции, например, CruiseControl, упомянутые вами, или Jenkins.

Смежные вопросы