メインコンテンツ

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

CERT C: Rec.MSC13-C

Detect and remove unused values

説明

ルール定義

未使用の値を検出して削除します。1

Polyspace 実装

ルール チェッカーは以下の問題をチェックします。

  • 未使用のパラメーターです

  • 読み取りのない書き込み

すべて展開する

問題

未使用のパラメーターですは、関数パラメーターが関数本体で読み取りも書き込みもされない場合に発生します。

リスク

未使用の関数パラメーターは、次の問題の原因となります。

  • コードが不完全である可能性が示される。パラメーターは、コーディングし忘れた操作用に想定されていた可能性があります。

  • コピーされたオブジェクトが大きいと、冗長なコピーによりパフォーマンスが低下する可能性がある。

修正方法

そのパラメーターは使用が意図されたものかどうかを判断します。意図されていない場合は、関数本体で使用されないパラメーターを削除します。

未使用のパラメーターを意図的に設けることもあります。たとえば、後で関数を機能拡張する際の使用が想定されたパラメーターを設けます。後日の使用が想定されている旨のコード コメントを追加してください。そのコード コメントは、作成者やコード レビュー担当者にとって、関数に未使用のパラメーターがある理由を理解するのに役立ちます。

あるいは、関数本体に (void)var; などのステートメントを追加します。var は未使用のパラメーターです。このステートメントへと拡張されたマクロを定義して、そのマクロを関数本体に追加することができます。

例 - 未使用のパラメーター
void func(int* xptr, int* yptr, int flag) { //Noncompliant
    if(flag==1) {
        *xptr=0;
    }
    else {
        *xptr=1;
    }
}

int main() {
    int x,y;
    func(&x,&y,1);
    return 0;
}

この例では、パラメーター yptrfunc の本体で使用されていません。

修正 — パラメーターを使用

1 つの修正方法として、そのパラメーターの使用が想定されていたかどうかをチェックします。そのパラメーターの使用が想定されていた場合は、コードを修正します。

void func(int* xptr, int* yptr, int flag) {
    if(flag==1) {
        *xptr=0;
        *yptr=1;
    }
    else {
        *xptr=1;
        *yptr=0;
    }
}

int main() {
    int x,y;
    func(&x,&y,1);
    return 0;
}
修正 — 未使用のパラメーターであることを明示

別の修正方法として、未使用のパラメーターについて認識していることを明示します。

#define UNUSED(x) (void)x

void func(int* xptr, int* yptr, int flag) {
    UNUSED(yptr);
    if(flag==1) {
        *xptr=0;
    }
    else {
        *xptr=1;
    }
}

int main() {
    int x,y;
    func(&x,&y,1);
    return 0;
}
問題

読み取りのない書き込みは、変数に代入された値が読み取られない場合に発生します。

たとえば、変数に値を書き込んだ後、前の値を読み取る前に 2 番目の値を書き込みます。この最初の書き込み操作は冗長です。

リスク

冗長な書き込み操作は多くの場合、プログラミング エラーを示します。たとえば、2 つの連続した書き込み操作の間に変数を読み取るのを忘れていたり、意図せずに別の変数を読み取っていたりします。

修正方法

変数に書き込んだが、後にその変数を読み取っていない理由を特定します。名前が似ている別の変数を誤って読み取っているなど、一般的なプログラミング エラーを探します。

書き込み操作が冗長であると判断したら、その操作を削除します。

例 - 読み取りを進めずに書き込むエラー
void sensor_amplification(void)
{
    extern int getsensor(void);
    int level;

    level = 4 * getsensor();             //Noncompliant
    /* Defect: Useless write */
}

変数 level に値 4 * getsensor() が代入された後、この値は読み取られていません。

修正 — 代入後に値を使用

1 つの修正方法として、代入後に変数 level を使用することができます。

#include <stdio.h>

void sensor_amplification(void)
{
    extern int getsensor(void);
    int level;

    level = 4 * getsensor(); 
    
    /* Fix: Use level after assignment */
    printf("The value is %d", level);
    
}

変数 level は新しい値を読み取ったうえで出力されます。

チェック情報

グループ: Rec.48.その他 (MSC)

バージョン履歴

R2019a で導入


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.