Vol.2015-SE-190 No.4
2015/12/15

情報処理学会研究報告
IPSJ SIG Technical Report

情報検索技術に基づく関数クローン検出を用いた変更管理システムの開発
佐野 真夢1,a)

吉田 則裕2

春名 修介1

井上 克郎1

概要：ソフトウェア保守における問題の 1 つとしてコードクローンが指摘されている. コードクローンとは, ソースコード中に存在する互いに一致または類似した部分を持つコード片のことである. あるコード片にバグがあると判明した場合, そのコードクローンにも同様のバグが存在する可能性がある. 従って, 関連する全てのコードクローンを調査し, 必要に応じて一貫した修正を行わなければならない. この際, 構文上一致しているコード片だけでなく, 構文上は異なるが同様の機能を実装しているコード片も調査すべきと考えられる. しかし, このような調査を修正の度に手動で実施することは非効率的である. この問題を解決するシステムとして, 修正が行われたコードのコードクローンを自動的に検出し, 通知する機能を持つコード
クローン変更管理システムが存在する. しかし, このシステムには, 構文上異なる実装を行っているコード
クローンを検出できないという問題がある. そこで, 本研究では, そのようなコードクローンも検出できる
新たなコードクローン変更管理システムの開発を行った. また, 本システムにより, 実際にどのようなコー
ドクローンが検出可能であるか調査を行った. その結果, 本システムが実際に構文上の違いを持つコードク
ローンに対する修正を検出できることを確認した.
キーワード：コードクローン，ソフトウェア保守，情報検索技術

Development of Change Management System
Using an IR-based Detection of Function Clones
Manamu Sano1,a)Norihiro Yoshida2

Shusuke Haruna1

Katsuro Inoue1

Abstract: Code clone has been known to be one of problems in software maintenance. It is a code fragmentthat is identical or similar to other code fragments in source code. If a code fragment has a bug, it is possiblethat other code clones have similar bugs. Therefore, developers must find all associated code clones to makeconsistent changes as necessary. They should find not only code clones that are the same syntactically, butalso clones that are diﬀerent syntactically and are implemented the same functionality. However, it is ineﬃcient to do it manually whenever they make changes. In order to solve this problem, a change management
system of code clones has been developed. However, this system has a problem that it is unable to detect
code clones including syntactic diﬀerences. In this study, we developed a novel change management systemof code clones that can detect such code clones. In addition, we evaluated what code clones our system canactually detect. Our evaluation shows that our system can actually detect code clones including syntactic
diﬀerences.
Keywords: Code Clone, Software Maintenance, Information Retrieval Technique

1

2

a)

大阪大学
Osaka University
名古屋大学
Nagoya University
m-sano@ist.osaka-u.ac.jp

c 2015 Information Processing Society of Japan⃝

1. まえがき
ソフトウェア保守工程における大きな問題の 1 つとして
コードクローンが指摘されている [1], [2], [5], [6], [10]. コー

1

Vol.2015-SE-190 No.4
2015/12/15

情報処理学会研究報告
IPSJ SIG Technical Report

ドクローンとは, ソースコード中に存在する互いに一致ま験について述べる. そして, 5 節で本研究のまとめと今後のたは類似した部分を持つコード片のことであり, 既存コー

課題について述べる.

ドのコピーアンドペーストによる再利用や, 定型処理の実装など様々な要因により生じる [2], [3].
一般的に, あるコード片にバグが存在することが判明し

2. 関連研究2.1 コードクローン

た場合, そのコードクローンにも同様のバグが存在する可コードクローンとは, ソースコード中に存在する互いに能性が考えられる. 従って, バグ修正を行う際には, 修正が一致または類似した部分を持つコード片のことである. 一加えられるコード片に対する全てのコードクローンを調査

般的に, コードクローンの存在はソフトウェア保守を困難

し, 必要に応じて一貫した修正を行う必要がある [9], [10].

にすると考えられている [3]. 例えば, あるコード片にバグ

性能改善や仕様変更など, 他の理由による修正においてもが見つかった場合, そのコードクローンにも同様のバグが同様のことが考えられる.

含まれる可能性が考えられる. そのため, コードクローン

また, 一貫した修正を考慮すべきコード片は構文上一致の存在を知ることは重要であるが, 特に大規模ソフトウェ

しているコードクローンだけとは限らない. 修正の種類

アとなると, 開発者がソフトウェアに含まれる全てのコー

によっては, 構文上は異なるが同様の機能を実装している

ドクローンを見つけることは非現実的である. 従って, 一

コードクローンに対する一貫した修正も検討する必要があ

般的には, ソフトウェア開発では自動検出ツールを用いてると考えられる. しかし, このような修正するコード片に

コードクローンの検出を行う [6].

対する全てのコードクローンを, 修正の度に手動で検出することは非常に手間がかかり, 非効率的である.
このような問題を解決するシステムとして, CloneNoti-

一般的に, 互いにコードクローンとなるコード片の対をクローンペアと呼び, クローンペアにおいて推移関係が成り立つコードクローンの集合をクローンセットと呼ぶ.

fier[13] が挙げられる. CloneNotifier とは, 修正が行われた

コードクローンは, いくつかのタイプに分類することがコード片に対するコードクローンを自動的に検出し, そのできる. Roy らは, コードクローンを以下の 4 つのタイプ

結果を開発者に通知する機能を持つコードクローン変更に分類している [12].

管理システムのことである. CloneNotifier を利用すれば,

タイプ 1

開発者は通知が行われた際に, 通知されたコードクローン
情報に基づいて一貫した修正の検討を行えばよいので, 修
正の際にコードクローンを意識する必要がなく, 開発者の負担を減らすことが可能である. また, システムが自動的にコードクローンを検出するため, 一貫した修正が必要な
コードクローンを見逃す可能性が大幅に減ると考えられる. CloneNotifier は検出部に CCFinder[6] と呼ばれるコー

空白・コメントの有無, レイアウトなどの違いを除いて完全に一致するコードクローン.
タイプ 2

タイプ 1 の違いに加えて, 変数名等のユーザ定

義名, 変数の型などが異なるコードクローン.
タイプ 3

タイプ 2 の違いに加えて, 文の挿入・削除・変更などが行われたコードクローン.
タイプ 4

同一の処理を実行するが, 文の並び替えなど構文上の実装が異なるコードクローン.

ドクローン検出ツールを利用しているが, これには構文上コードクローンの検出手法は主に, 構文の類似性に着目は異なるが同様の機能を実装しているコードクローンを検した検出手法 [2], [6], [10] と意味的な類似性 [4], [8], [14] に出できないという欠点がある. 上述したように, このよう着目した検出手法に分類できる. 両者共そのアプローチはなコードクローンも一貫した修正が必要な可能性は考えら様々であるが, 構文の類似性に着目した手法では主にタイれるため, これらを検出できれば, 一貫した修正を見逃す可プ 1,2,3 を, 意味的な類似性に着目した手法では全タイプの能性のさらなる削減が期待できる.

コードクローンを検出できる.

そこで本研究では, 構文上一致しているコードクローンだ
けでなく, 構文上は異なるが同様の機能を実装しているコー

2.2 コードクローン検出ツール

ドクローンも検出できるコードクローン検出ツールを用い

コードクローンの検出のために様々な手法が考案され,て新たなコードクローン変更管理システムの開発を行った.

それを実装した検出ツールが開発されている. 本節では,また, 本システムを OSS の過去の開発履歴に対して適用し,本研究に関連する 2 つのコードクローン検出ツールを紹介

実際にどのようなコードクローンが検出されるか調査を実する.

施した. 本調査の結果, 本システムが CloneNotifier では検

2.2.1 CCFinder

出できないコードクローンの修正を検出できることが確認した.

CCFinder[6] は, 構文の類似性に着目した手法を用いた
コードクローン検出ツールの 1 つであり, ソースコード中に以降, 2 節では本研究に関連する研究について説明する.

ある同一文字列を字句単位で検索することでコードクロー

また, 3 節では本研究で開発したコードクローン変更管理

ン検出を行う. CCFinder は高いスケーラビリティを有しシステムについて説明し, 4 節では本研究で行った評価実ており, 大規模なソフトウェアに対しても実用的な時間で

c 2015 Information Processing Society of Japan⃝2

Vol.2015-SE-190 No.4
2015/12/15

情報処理学会研究報告
IPSJ SIG Technical Report

コードクローンを検出できる. CCFinder は実際に様々な大規模ソフトウェアに適用され, その有用性が確認されている [11]. しかし, 検出可能なコードクローンはタイプ 1, 2
のみであり, タイプ 3 以上は検出できない.

2.2.2 山中らのツール
山中らのツール [14] は, 意味的な類似性に着目した手法

修正前
1 void AscendingSort(int list[]) {2
int i, j, temp;
3
for(i = 0; i < n-1; i++)4
for(j=n-1; j > i; j--)5
if(list[j+1] > list[j]) {6
temp = list[j];7list[j] = list[j-1];
8
list[j-1] = temp;
9
}
10
}

1 void DescendingSort(int list[]) {2
int i, j, temp;
3
for(i = 0; i < n-1; i++)4
for(j=n-1; j > i; j--)5
if(list[j+1] < list[j]) {6
temp = list[j];7list[j] = list[j-1];
8
list[j-1] = temp;
9
}
10
}

1 void AscendingSort(int list[]) {2
int i, j, temp;
3
for(i = 0; i < n-1; i++)4
for(j=n-1; j > i; j--)5
if(list[j-1] > list[j]) {6
temp = list[j];7list[j] = list[j-1];
8
list[j-1] = temp;
9
}
10
}

1 void DescendingSort(int list[]) {2
int i, j, temp;
3
for(i = 0; i < n-1; i++)4
for(j=n-1; j > i; j--)5
if(list[j-1] < list[j]) {6
temp = list[j];7list[j] = list[j-1];
8
list[j-1] = temp;
9
}
10
}

を用いたコードクローン検出ツールの 1 つであり, 情報検索技術を用いることで関数単位のコードクローン（以下,関数クローンと呼ぶ）の検出を行う. 具体的には, 関数中で用いられているユーザ定義名に基づいて, 関数同士の類似度を求めることでコードクローンを検出している. すな
わち, 登場するユーザ定義名が似ていれば, 関数クローンと修正後なる. 山中らのツールは全タイプのコードクローンの検出が可能であり, また, 他の意味的な類似性に着目した手法を

図 1 タイプ 3 コードクローンの一貫した修正の例

用いた検出ツールよりも高速にコードクローンを検出する

Fig. 1 Example of consistent changes for type-3 code clones.

ことができる.

2.3 クローン変更管理システム

1. ソースコードの取得

2. コードクローンの検出

2.1 節で述べたのように, あるコード片にバグが存在することが判明した場合, そのコードクローンにも同様のバグが存在する可能性が考えられる. また, 性能改善や仕様変版管理システム

クローン検出ツール
3. 変更情報に基づきコードクローンを分類

変更された
コードクローンを把握

更といった他の修正においても, 同様の修正を複数のコー
ドクローンに対して適用しなければならない可能性がある.

コードクローン
変更管理システム

そのため, 修正が加えられるコード片に対する全てのコー

開発者

4. コードクローンの分類結果の提示ドクローンを調査し, 必要に応じて一貫した修正を行わなければならない. このような一貫した修正は, 全タイプのコードクローンに適用できる可能性が存在している. 修正

図 2

CloneNotifer の通知プロセス

Fig. 2 Notification process of CloneNotifier.

するコード片に対するコードクローンを修正の度に検出し,一貫した修正の必要性があるか検討することは非効率的でかし, このコードクローンは 5 行目の比較演算子が異なあると考えられる.

るためタイプ 3 コードクローンに分類される. それゆえ,上述の問題を解決するために, CloneNotifier[13] を利用

CloneNotifier ではこのコードクローンを検出できない. そすることが考えられる. CloneNotifier とは, コードクローの原因は, CCFinder がタイプ 3, 4 のコードクローンを検ンの変更を管理するシステムであり, 修正されたコード片

出できないことに起因する. コードクローンの変更管理にがコードクローンを持つ場合, そのクローンセットを一貫おいては, 全てのタイプを検出可能なコードクローン検出

した修正を検討すべきものとして開発者に自動で通知するツールを利用する方が望ましいと考えられる.

機能を持つ. コードクローンの検出には, 2.2.1 節で説明し

図 2 は, CloneNotifier において, 修正されたコードク

た CCFinder が利用されている. 従って, CloneNotifier はローンを開発者に通知するまでのプロセスを示した図であタイプ 1, 2 のコードクローンを管理できるシステムといる. 通知プロセスは, 下記のような手順で通知が行われる.

える.

( 1 ) 版管理システムから最新のソースコードを取得する.

しかし, 一貫した修正はタイプ 3, 4 のコードクローンにも適用しなければならない可能性はある. 図 1 は, 一貫しこの際, 以前のバージョンのソースコードを移動して保持する.

た修正が行われたコードクローンの例である. 図 1 の関

( 2 ) 取得した最新のソースコードと, 以前のバージョンの数 AcendingSort(),DescendingSort はそれぞれ昇順, 降

ソースコードからコードクローンの検出を行う.

順のバブルソートを行う関数であり, 5 行目の比較におい( 3 ) コードクローンの検出結果と, 変更情報に基づいてて list[j-1] と比較すべきところを, list[j+1] と比較

コードクローンを分類する. 分類は修正されたか否かするという共通のバグを含んでいる. 従って, 一方を修正の他, 新たにコードクローンとして追加された, コードした際に, 一貫した修正の対象として CloneNotifier はこ

クローンではなくなった, 異なるコード片とクローンのコードクローンを通知すべきであると考えられる. しセットを構成するようになった場合も考慮される.

c 2015 Information Processing Society of Japan⃝3

Vol.2015-SE-190 No.4
2015/12/15

情報処理学会研究報告
IPSJ SIG Technical Report( 4 ) コードクローンの分類結果を開発者に通知する. 通知含むファイル名は出力するが, その位置情報は出力しない.

方法は電子メール（テキスト）, CSV, html 形式の 3

そのため, 新たにコードクローンの位置特定を行う機能を種類が存在する.

実装する必要があった. すなわち, 手順 2. の実施後にク

また, 特定の 2 バージョンを指定した比較も可能であり,ローンとなっている関数名とそれを含むファイルの情報か

過去の開発履歴から修正されたクローンセットを検出する

ら位置情報を特定する. 具体的には, 提示されたファイルことも可能である.

から該当する関数の宣言部を探索し, その宣言の開始トー3. 関数クローン検出を用いた変更管理システ
ムの開発
本研究では, 2.3 節で説明した CloneNotifier をベースにして, コードクローン検出部分を CCFinder から山中らのクン（返り値の型, アクセス修飾子等）をコードクローンの開始位置, 終了トークン「}」をコードクローンの終了位
置として特定を行う.

4. 評価実験ツール（2.2.2 節参照）に置き換える形で関数クローン検出

本研究では, 開発したコードクローン変更管理システムを用いた変更管理システムを開発した. 山中らのツールをの有用性を評価するための調査を行った. 本節では, 実施

利用することで, 全タイプのコードクローンの変更を検出,した調査の内容と結果, そこから得られる考察について説

通知することが可能になると期待できる. 本節では, 開発

明する.

した変更管理システムの実装について説明する.
本システムの通知プロセスは, 図 2 に示した CloneNoti-

4.1 実験内容
本実験では, 開発したコードクローン変更管理システム

fier の手順とほとんど同様であり, 下記のような手順で通知が行われる.

の有用性に関する評価を行う. 具体的には, 評価対象とな( 1 ) 版管理システムから最新のソースコードを取得する.

るシステムの過去の開発履歴に対して実際に本システムを

この際, 以前のバージョンのソースコードを移動して適用することで, どのような結果が得られるかを調査する.
本システムの主な目的は, CloneNotifer では検出できな保持する.

( 2 ) 取得した最新のソースコードと, 以前のバージョンのソースコードから関数クローンの検出を行う.

( 3 ) 関数クローンの位置特定を行う.

いタイプ 3, タイプ 4 のクローンセットの修正を見つけ出すことにある. このようなクローンセットを検出できなけ
れば, 本システムが有用であるとは言えない. ゆえに, 本実( 4 ) コードクローンの検出結果と, 変更情報に基づいて

験では, CloneNotifer では検出できないクローンセットの

コードクローンを分類する. 分類は修正されたか否か修正に着目し, これらがどの程度, 検出できているかを評価の他, 新たにコードクローンとして追加された, コードする.
評価対象には, PostgreSQL*1 と呼ばれる C 言語で記述

クローンではなくなった, 異なるコード片とクローンセットを構成するようになった場合も考慮される.

されたデータベース管理システムを使用する. 期間は( 5 ) コードクローンの分類結果を開発者に通知する. 通知

2005/01/01〜2005/06/30 までの 6 ヶ月間とし, 1 週間単位

方法は電子メール（テキスト）, CSV, html 形式の 3で全 26 期間の修正クローンセットの検出を行った. Post-

種類が存在する.

greSQL を評価対象にした理由として, 開発リポジトリが基本的な部分は CloneNotifier と同様であるため, 特定の 2

公開されており, 過去の開発履歴を容易に取得できることバージョンを指定した比較も可能である.

が挙げられる. また, PostgreSQL は様々なコードクローン

本研究では, CloneNotifier のコードクローン検出部分に研究で利用され [7], [10], ある程度の量のコードクローンが着目している. 従って, 手順 2. のコードクローン検出以外

存在していることが判明していることも理由である. 対象の機能に関しては, CloneNotifier のソースコードを流用すシステムにコードクローン自体が存在しなかった場合, 本ることが可能である. コードクローン検出に関しては, 使

実験は意味を成さないため, ある程度のコードクローンが用するツールを CCFinder から山中らのツールに置き換え存在する対象を選択する必要があった.
実 際 の 評 価 手 順 は 以 下 の よ う に な る.

る必要がある. また, CCFinder と山中らのツールでは入出

こ こ で は,力仕様や出力される情報が異なるため, 他の手順の実装も2005/01/01〜2005/01/07 の期間を例に説明を行う.

適宜修正を加える必要がある.

( 1 ) 本システムを適用する 2 バージョンのソースコー

本システムの出力情報には, コードクローンの位置情報

ドを入手する. 2005/01/01 時点のソースコードは,（開始・終了行番号, 列番号）が含まれる. CloneNotifier に

2005/01/01 の 0 時 0 分 0 秒時点でのソースコードとおいては, CCFinder の検出結果にコードクローンの位置する（以降, これを旧バージョンと呼ぶ）. すなわち,情報が存在していたため, その情報を用いることができた.
しかし, 山中らのツールは関数クローンの関数名やそれをc 2015 Information Processing Society of Japan⃝*1

http://www.postgresql.org/

4Vol.2015-SE-190 No.4
2015/12/15

情報処理学会研究報告
IPSJ SIG Technical Report
表 1

本システムで検出された PostgreSQL の修正クローンセット

られる. しかし, バグの修正漏れ等のコードに対する一貫の数

した修正の問題とは本質が異なると考えられるため, 本実

Table 1 The number of modified clone sets in postgreSQL using the proposed system.

験では別途数えている. 「その他」は一貫した修正を受けていないクローンが存在し, 修正を適用することができな

notCN

その他

合計

い, あるいは, 適用する必要が無いことがコードから明らか

126

219

345

に読み取れるものである.
本システムでは, コードクローンの修正を自動的に検出取得するのは 2005/01/01 の 0 時 0 分 0 秒以前におけし, それを開発者に通知することで, コードクローンに一る最終バージョンとなる. 2005/01/07 時点のソース

貫した修正が行われたか, あるいは, 行う必要があるかをコードは, 2005/01/08 の 0 時 0 分 0 秒以前の最新ソー

効率良くチェックできるようにすることを目的としていスコードとする. すなわち, 取得するのは 2005/01/07

る. 従って, 本システムにとって有用なクローンセットは,の最終バージョンとなる（以降, これを新バージョン

実際に一貫した修正が行われたクローンセット（表 2 のと呼ぶ）. なお, 最終期間（2005/06/25〜2005/06/30）

consistent）, 及び, 一貫した修正が適用可能なクローンセッ

は 7 日間ではないが, 2005/06/30 時点を新バージョント（表 2 の inconsistent）であると考えられる. 表 2 より,とする.

( 2 ) 検出結果に基づいて, 1 つでも修正された関数クローンを含むクローンセットを抽出する.

( 3 ) 抽出したクローンセットを以下の 3 種類に分類する.

本システムで検出可能だが, CloneNotifier で検出不可能な修正クローンセットのうち, 約 7 割が有用なクローンセッ
トであるとわかる. 従って, 本システムでのみ検出可能な
コードクローンの修正の多くが有用なクローンセットであ• 全ての関数クローンが一貫した修正を受けた.

り, これらを検出できることは, 本システムの大きな強みで• 修正をされていない場合を含み, 一貫した修正を受けあると考えられる.

ていない関数クローンが存在する. しかし, 修正を受

本実験において実際に検出されたクローンセットの例をけていない関数クローンにも, その修正を適用できる

図 3 に示す. 図 3 は, 本実験において実際に検出された有用可能性がある.

な修正クローンセットの 1 つである. 修正は, 2005/03/12〜• 一貫した修正を受けていない関数クローンが存在し,2005/03/18 の期間に行われたものであり, 2 つの関数は共その修正を適用することはできない. または, 不要でに printtup.c に含まれている. なお, 行番号は説明のたあることが明らかにわかる.

めに再度割り当てたものであり実際とは異なる. 2 つの関
数 printup, printup_internal_20 は共にデータベースの4.2 実験結果と考察

タプルの情報出力に関する関数であり, 多くの共通処理を本実験により得られた, PostgreSQL において修正された含む関数クローンとなっている. 図 3 から, 2 つの関数は,クローンセットの数を表 1 に示す. 表 1 において,「notCN」

printup_internal_20 が独自のローカル変数を定義しては CloneNotifier で検出できないと考えられる修正クローいる（printup_internal_20 の修正前後共に 12 行目）,

ンセットである. 「その他」は, CloneNotifier で検出可能

printup にのみ関数呼出しが存在する（printup の修正前

な修正クローンセットの他, そのバージョンで新たに追加

後共に 14 行目）などの差分を含むため, この関数クローされた関数クローンなど, コード自体の修正以外の理由でン（及び図のコード片）は, タイプ 3 であることがわかる.

検出されたものも含まれている. 表 1 から, CloneNotifier

従って, CloneNotifier では検出できない. しかし, 修正されで検出不可能な修正クローンセットが約 4 割検出されていた内容（図 3 の赤字部分）を見ると, その修正が同様のもることがわかるが,のであることがわかる. 従って, これら 2 つの関数クロー

また, CloneNotifier で検出できない修正クローンセット
を分類すると表 2 のようになる. 表 2 において, 「consis-

ンに対する修正は一貫した修正であり, これらは有用なク
ローンセットの 1 つであるといえる.

tent」はクローンセット中の全てのクローンが一貫した修

また, 図 4 はデータベースサーバの制御に関する関数ク正を受けたものの数を示している. 「inconsistent」は一貫

ローンである. 修正は, 2005/04/30〜2005/05/06 の期間にした修正を受けていないクローンが存在し, なおかつ, その

行われたものであり, 2 つの関数は共に pg_ctl.c に含まれクローンに一貫した修正の一部でも適用できる可能性があている. 図 4 のコード片は, 2 つの関数のエラー処理に関するものを示している. 「comment and forming」はコードる部分である. do_restart の修正前における 10 行目の呼整形やコメントの修正のみ行われた場合である. この場合,出し関数にあたるコードが do_stop には存在しないため,一貫しているか否かは考慮していない. ドキュメント作成

2 つの関数はタイプ 3 のコードクローンであるといえる.

やコーディング規約の遵守の観点から見ると, 整形やコメ

しかし, 図 4 の修正では, do_restart に対してのみ 7 行目

ント修正が行われたクローンセットは有用であるとも考え（修正後）の if 文を追加しており, do_stop にはこの修正がc 2015 Information Processing Society of Japan⃝5

Vol.2015-SE-190 No.4
2015/12/15

情報処理学会研究報告
IPSJ SIG Technical Report
表 2

CloneNotifier で検出できない修正クローンセットの内訳

Table 2 Classification of modified clone sets that CloneNotifier cannot detect.
consistent

inconsistentcomment and forming

その他

合計

73

16

32

5

126

修正前
1
2
3
・
・
・
4
5
6
7
8
9
10
11
12
13
14
15
16
・
・
・
17
1
2
3
・
・
・
4
5
6
7
8
9
10
11
12
13
14
・
・
・
15

修正後

static void
printtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self)
{

1
2
3
・
・
・
4
5
6
7
8
9
10
11
12
13
14
15
16
・
・
・
17

前略
/*
* send the attributes of this tuple*/for (i = 0; i < natts; ++i){
PrinttupAttrInfo *thisState = myState->myinfo + i;
Datum origattr = myState->values[i],attr;
if (myState->nulls[i] == 'n'){pq_sendint(&buf, -1, 4);continue;}
後略}

static void
printtup_internal_20(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self){
前略/** send the attributes of this tuple*/for (i = 0; i < natts; ++i){
PrinttupAttrInfo *thisState = myState->myinfo + i;
Datum origattr = myState->values[i],attr;bytea *outputbytes;
if (myState->nulls[i] == 'n')continue;
後略
}

1
2
3
・
・
・
4
5
6
7
8
9
10
11
12
13
14
・
・
・
15

static void
printtup(TupleTableSlot *slot, DestReceiver *self){
前略/** send the attributes of this tuple*/for (i = 0; i < natts; ++i){
PrinttupAttrInfo *thisState = myState->myinfo + i;
Datum origattr = slot->tts_values[i],attr;
if (slot->tts_isnull[i]){pq_sendint(&buf, -1, 4);continue;}
後略}

static void
printtup_internal_20(TupleTableSlot *slot, DestReceiver *self){
前略/** send the attributes of this tuple*/for (i = 0; i < natts; ++i){
PrinttupAttrInfo *thisState = myState->myinfo + i;
Datum origattr = slot->tts_values[i],attr;bytea *outputbytes;
if (slot->tts_isnull[i])continue;
後略}

図 3 本実験における有用なクローンセットの検出事例 (タプル出力に関するクローン)

Fig. 3 Example of usefull cloneset in our evaluation (clones on printing tuples).

行われていない. 従って, この事例では, do_stop に対して作業で実施している. 従って, 分類にヒューマンエラーが含同様の一貫した修正を加えるべきかどうか検討すべきであまれる可能性を否定できない. もし誤りがあれば, 本実験

ると考えられる. ゆえに, この関数クローンに対する修正の結果は異なるものになると考えられる. しかし, クローは, 有用なクローンセット検出事例の 1 つであるといえる.

ンセットに行われた修正が一貫したものであるか否かを判断するには, 最終的には人間がコードを確認しなければな

4.3 妥当性への脅威

らず, 完全な自動化は難しい. よって, 正確な結果を得るた

本実験では, 評価対象として PostgreSQL の特定の期間

めには, より多くの研究者や, 評価対象の開発者の協力を得を選択したが, 期間に応じて行われる修正の量や種類は異て, 分類を実施する必要があるだろう. しかし, 本システム

なる. 従って, 異なる期間を選択すれば, 本実験とは異なが, 図 3, 図 4 といった CloneNotifier には検出できないタる結果が得られる可能性が考えられる. また, 評価対象に

イプ 3 の修正クローンセットを検出できることは, 実験結

異なるシステムを選択した場合も, 同様に異なる結果が得果から明らかである. ゆえに, 本システムが CloneNotifier

られる可能性がある. どちらの場合も, タイプ 3 のコードより有用な点を持つことは確実であると考えられる.

クローンに対する修正が含まれる場合は, 量に差はあれどCloneNotifier には検出できない修正クローンセットが検出

5. まとめと今後の課題

できると考えられる. しかし, タイプ 3 のコードクローンに

本研究では, 修正されたコードのコードクローンを自対する修正が存在しない場合, 本システムが CloneNotifier

動的に検出・通知するコードクローン変更管理システム

より有用であるといえる結果が得られないだろう.

CloneNotifier をベースに, そのコードクローン検出部をまた, 本実験では, 表 2 の修正クローンセットの分類を手

c 2015 Information Processing Society of Japan⃝

CCFinder から山中らのツールに置き換えることで, タイ6Vol.2015-SE-190 No.4
2015/12/15

情報処理学会研究報告
IPSJ SIG Technical Report

修正前
1
2
3
・
・
・
4
5
6
7
8
9
10
11
・
・
・
12
1
2
3
・
・
・
4
5
6
7
8
9
10
11
12
・
・
・
13

修正後

static void
do_stop(void)
{

1
2
3
・
・
・
4
5
6
7
8
9
10
11
・
・
・
12

前略
else if (pid < 0){
pid = -pid;
write_stderr(_("%s: cannot stop postmaster; ""postgres is running (PID: %ld)\n"),progname, pid);exit(1);}
後略}

static void
do_restart(void){
前略else if (pid < 0){
pid = -pid;
write_stderr(_("%s: cannot restart postmaster; ""postgres is running (PID: %ld)\n"),progname, pid);
write_stderr(_("Please terminate postgres and try again.\n"));exit(1);
}
後略
}

図 4

1
2
3
・
・
・
4
5
6
7
8
7
8
9
10
11
12
13
・
・
・
14

static void
do_stop(void){
前略else if (pid < 0){
pid = -pid;
write_stderr(_("%s: cannot stop postmaster; ""postgres is running (PID: %ld)\n"),progname, pid);exit(1);}
後略}

static void
do_restart(void){
前略else if (pid < 0){
pid = -pid;
if (postmaster_is_alive((pid_t) pid)){
write_stderr(_("%s: cannot restart postmaster; ""postgres is running (PID: %ld)\n"),progname, pid);
write_stderr(_("Please terminate postgres and try again.\n"));exit(1);}}
後略}

本実験における有用なクローンセットの検出事例 (データベース制御に関するクローン)

Fig. 4 Example of usefull cloneset in our evaluation (clones on database control).

プ 1〜4 の全てのコードクローンに対応した新しいコード

参考文献

クローン変更管理システムを開発した. また, PostgreSQL[1]に本システムを実際に適用し, CloneNotifier では検出できない多くの有用なコードクローンを検出できていることを

[2]

確認した.
今後の課題として, CloneNotifier との比較評価を行う必要があると考えられる. 現時点では, CloneNotifier が検出[3]

できず, 開発したシステムが検出できるコードクローンを確認したのみであり, その逆に, 開発したシステムが検出[4]できず, CloneNotifier のみが検出できるコードクローンが存在する可能性もある. また, 厳密な議論を行うためには,[5]

定量的な評価も必要あると考えている. その他, 本システ
ムの対応言語の拡張も必要と考えられる. CloneNotifier は[6]Java や C, COBOL や C#など数多くのプログラミング言語に対応しているが, 本システムでは, そのうち Java と Cにしか対応していない. これは, 各々が使用するコードク[7]

ローン検出ツールの対応言語に起因している. ただし, 山中らのツールで用いられている関数中のユーザ定義名の類[8]

似度に基づくクローン検出手法はプログラミング言語にほとんど依存せず適用できる. そのため, 関数やそれに類す[9]る概念のあるプログラミング言語であれば, 対応は容易と考えられる.
謝辞

本研究は JSPS 科研費 25220003，26730036 の助成を受けたものてす.

c 2015 Information Processing Society of Japan⃝[10]

Baker, B. S.: Finding Clones with Dup: Analysis of anExperiment, IEEE Transactions on Software Engineering, Vol. 33, No. 9, pp. 608–621 (2007).
Baxter, I. D., Yahin, A., Moura, L., Sant’Anna, M. andBier, L.: Clone detection using abstract syntax trees, pp.
368–377 (1998).
肥後芳樹，楠本真二，井上克郎：コードクローン検出とその関連技術，電子情報通信学会論文誌，Vol. J91-D, No. 6,
pp. 1465–1481 (2008).
肥後芳樹，楠本真二：プログラム依存グラフを用いたコー
ドクローン検出法の改善と評価，情報処理学会論文誌，Vol. 51, No. 12, pp. 2149–2168 (2010).
Jiang, L., Misherghi, G., Su, Z. and Glondu, S.:
DECKARD: Scalable and accurate tree-based detectionof code clones.
Kamiya, T., Kusumoto, S. and Inoue, K.: CCFinder: A
multilinguistic token-based code clone detection system
for large scale source code, IEEE Transactions on Software Engineering, Vol. 28, No. 1, pp. 654–670 (2002).
川口真司，松下 誠，井上克郎：版管理システムを用いたクローン履歴分析手法の提案，電子情報通信学会論文
誌，Vol. J89-D, No. 10, pp. 2279–2287 (2006).
Kim, H., Jung, Y., Kim, S. and Yi, K.: MeCC: memory
comparison-based clone detector, pp. 301–310 (2011).
Laguë, B., Proulx, D., Mayrand, J., Merlo, E. M. and
Hudepohl, J.: Assessing the Benefits of Incorporating
Function Clone Detection in a Development Process, pp.
314–321 (1997).
Li, Z., Lu, S., Myagmar, S. and Zhou, Y.: CP-Miner:
Finding copy-paste and related bugs in large-scale software code, IEEE Transactions on Software Engineering, Vol. 32, No. 3, pp. 176–192 (2006).

7

情報処理学会研究報告
IPSJ SIG Technical Report

[11]

[12]

[13]

[14]

Vol.2015-SE-190 No.4
2015/12/15

門田暁人，佐藤慎一，神谷年洋，松本健一：コードクローンに基づくレガシーソフトウェアの品質の分析，情報処
理学会論文誌，Vol. 44, No. 8, pp. 2178–2188 (2003).
Roy, C. K., Cordy, J. R. and Koschke, R.: Comparison and evaluation of code clone detection techniques
and tools: a qualitative approach, Science of Computer
Programming, Vol. 74, No. 7, pp. 470–495 (2009).
山中裕樹，崔 恩瀞，吉田則裕，井上克郎，佐野建樹：
コードクローン変更管理システムの開発と実プロジェク
トへの適用，情報処理学会論文誌，Vol. 54, No. 2, pp.
883–893 (2013).
山中裕樹，崔 恩瀞，吉田則裕，井上克郎：情報検索技術に基づく高速な関数クローン検出，情報処理学会論文誌，Vol. 55, No. 10, pp. 2245–2255 (2014).

c 2015 Information Processing Society of Japan⃝

8