メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

重複しているコード

コード セクションが他の場所で重複している

R2023a 以降

説明

この欠陥は、コード ブロックが複数の場所で重複している場合に発生します。

欠陥チェッカーは重複として特定のブロックにフラグを設定することはしません。たとえば一般的に言って、ほぼ重複していると見なされるコード ブロックは、一定の行数以上で構成されています。Polyspace Bug Finder での重複コード検出も参照してください。

リスク

同じ操作を行うコードのセクションが複数あると、保守が不必要に増えることになります。さらに、コードが重複していると、ある場所ではコードを更新したのに、別の場所では更新し忘れるということが発生する可能性が高くなります。"ほぼ重複しているコード" および "コピーして貼り付けのエラーの可能性あり" も参照してください。

修正方法

コードのセクションを専用の関数にリファクタリングします。つまり、2 つのコード ブロックが互いに重複している場合は、このコード ブロックを含む新しい関数を記述し、重複している既存のブロックをこの新しい関数の呼び出しで置き換えます。

すべて展開する

この例には、互いに完全に重複する 2 つのコード ブロックが含まれています。

typedef struct {
    int pin1;
    int pin2;
    int pin3;
    int pin4;
    int pin5;
    int pin6;
    int pin7;
    int pin8;
} board;

board Aboard;
extern int getPinVal();

void setAllPins() {
     int val1 = getPinVal();
     int val2 = getPinVal();
     int val3 = getPinVal();
     int val4 = getPinVal();
     int val5 = getPinVal();
     int val6 = getPinVal();
     int val7 = getPinVal();
     int val8 = getPinVal();
     Aboard.pin1 = val1; //Beginning of duplicate section #1
     Aboard.pin2 = val2;
     Aboard.pin3 = val3;
     Aboard.pin4 = val4;
     Aboard.pin5 = val5;
     Aboard.pin6 = val6;
     Aboard.pin7 = val7;
     Aboard.pin8 = val8; //End of duplicate section #1

}

void resetAllPins() {
     int val1 = 0, val2 = 1, val3 = 0,
         val4 = 0, val5 = 1, val6 = 0,
         val7 = 0, val8 = 1;
     Aboard.pin1 = val1; //Beginning of duplicate section #2
     Aboard.pin2 = val2;
     Aboard.pin3 = val3;
     Aboard.pin4 = val4;
     Aboard.pin5 = val5;
     Aboard.pin6 = val6;
     Aboard.pin7 = val7;
     Aboard.pin8 = val8; //End of duplicate section #2
}

[結果の詳細] ペインのイベント リストには、各コード ブロックの先頭と末尾が示されます。イベントをクリックすると、ソース コード内の対応する場所に移動します。

Event list shows beginning and end of each duplicate section

Polyspace® ユーザー インターフェイスの [ソース] ペインでは、重複しているコード ブロックを左右に並べて表示できます。個別のウィンドウでの移動を参照してください。

修正 – 重複しているセクションを共通の関数にリファクタリング

重複しているコード セクションを共通の関数にリファクタリングし、それらのセクションをこの関数の呼び出しで置き換えることができます。この例では、重複するブロックが関数 init() にリファクタリングされています。

typedef struct {
    int pin1;
    int pin2;
    int pin3;
    int pin4;
    int pin5;
    int pin6;
    int pin7;
    int pin8;
} board;

board Aboard;
extern int getPinVal();

void init(int val1, int val2, int val3, int val4,
          int val5, int val6, int val7, int val8) {
     Aboard.pin1 = val1;
     Aboard.pin2 = val2;
     Aboard.pin3 = val3;
     Aboard.pin4 = val4;
     Aboard.pin5 = val5;
     Aboard.pin6 = val6;
     Aboard.pin7 = val7;
     Aboard.pin8 = val8; 
}

void setAllPins() {
     int val1 = getPinVal();
     int val2 = getPinVal();
     int val3 = getPinVal();
     int val4 = getPinVal();
     int val5 = getPinVal();
     int val6 = getPinVal();
     int val7 = getPinVal();
     int val8 = getPinVal();
     init(val1, val2, val3, val4, val5, val6, val7, val8);
}

void resetAllPins() {
     int val1 = 0, val2 = 1, val3 = 0,
         val4 = 0, val5 = 1, val6 = 0,
         val7 = 0, val8 = 1;
     init(val1, val2, val3, val4, val5, val6, val7, val8);
}

結果情報

グループ: 適切な手法
言語: C | C++
既定値: オフ
コマンド ライン構文: DUPLICATED_CODE
影響度: Low

バージョン履歴

R2023a で導入

すべて展開する