メインコンテンツ

CWE Rule 483

Incorrect Block Delimitation

R2023a 以降

説明

ルールの説明

The code does not explicitly delimit a block that is intended to contain 2 or more statements, creating a logic error.

Polyspace 実装

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

  • ステートメントのインデントが正しくありません

  • if、for、または while ステートメントと同じ行にあるセミコロン

すべて展開する

問題

この問題は、ステートメントのインデントが ifelse、またはその他のブロックの一部として表示されるが、並べ替えや中かっこの欠如によって、実際にはステートメントがブロックの外側に配置される場合に発生します。

リスク

開発者またはレビュー担当者がインデントに基づいて間違ってステートメントとブロックを関連付けることによって、プログラム ロジックに関する間違った前提につながる可能性があります。

以下に例を示します。

if(credentialsOK())
   login=1;
   setCookies();
setCookies();if ブロックの一部ではありませんが、インデントがそうでないことを示唆しています。

修正方法

ステートメントをブロックの一部にするには、ステートメントがブロックに関連付けられた中かっこ内に存在することを確認します。ブロックの範囲を特定するには、[ソース] ペインで、開いている中かっこをクリックします。

ifelse、または while ステートメントに中かっこに続く条件が含まれていない場合は、セミコロンまでの実行パス上の次の行のみが ifelse、または while ブロックの一部と見なされます。後続の行をブロック内に含めるには、その行を中かっこでラップします。

たとえば、前述の例で、両方のステートメントを if ブロック内に含めるには、以下を使用します。

if(credentialsOK()) {
   login=1;
   setCookies();
}

例 — 間違ってインデントされた else ステートメント
int switch1, switch2;

void doSomething(void);
void doSomethingElse(void);

void func() {
    if(switch1) 
        if(switch2)
            doSomething();
    else //Noncompliant
        doSomethingElse();
}

この例では、else が 1 つ目の if に関連付けられているかのようにインデントされています。しかし、実際には、else は 2 つ目の if に関連付けられています。インデントが実際の関連付けと一致しないため、プログラム ロジックに関する誤った前提につながる可能性があります。

修正 — 中かっこを適切に使用する

else を 1 つ目の if に関連付けるには、中かっこを使用して 1 つ目の if ブロックの境界をマークします。

int switch1, switch2;

void doSomething(void);
void doSomethingElse(void);

void func() {
    if(switch1) { 
        if(switch2)
            doSomething();
    }
    else
        doSomethingElse();
}
問題

この問題は、iffor、または while ステートメントの最後のトークンと同じ行にセミコロンがあると、本体が空になるために発生します。

チェッカーは、if ステートメントの直後に else ステートメントが続くケースを例外として許可します。

if(condition);
else {
  ...
}

リスク

if、for、または while ステートメントに続くセミコロンは、多くの場合、プログラミング エラーを示しています。誤ったセミコロンは、実行フローを変更し、意図しない結果につながります。

修正方法

iffor、または while ステートメントの本体を空にする場合は、次のように、ブロックでセミコロンをラップし、そのブロックを新しい行に配置して意図を明確に示します。

if(condition)
   {;}
または、誤ったセミコロンを削除します。

例 — 誤ったセミコロン
int credentialsOK(void);

void login () {
    int loggedIn = 0;
    if(credentialsOK()); //Noncompliant
      loggedIn = 1; //Noncompliant
}

この例では、誤ったセミコロンによって if の本体が空になります。代入 loggedIn=1 は必ず実行されます。ただし、代入はある条件下でしか実行されない可能性があります。

修正 – 誤ったセミコロンを削除する

セミコロンが意図されたものでなければ、そのセミコロンを削除します。

int credentialsOK(void);

void login () {
    int loggedIn = 0;
    if(credentialsOK())
      loggedIn = 1;
}

チェック情報

カテゴリ: Behavioral Problems

バージョン履歴

R2023a で導入