メインコンテンツ

MISRA C++:2023 Rule 8.14.1

The right-hand operand of a logical && or || operator should not contain persistent side effects

R2024b 以降

説明

ルール定義

The right-hand operand of a logical && or || operator should not contain persistent side effects. 1

根拠

|| 演算子の右オペランドは左オペランドが true の場合、評価されません。&& 演算子の右オペランドは左オペランドが false の場合、評価されません。これらの場合、右オペランドが変数値を変更しても、変更は発生しません。

Polyspace 実装

ルール チェッカーは、論理演算子 || または && の右オペランドに永続的な二次的影響が含まれる状況を報告します。たとえば、右オペランドに関数呼び出しが含まれており、この関数がグローバル変数を変更する場合、ルール チェッカーは違反を報告します。

純粋な関数、つまり二次的影響を伴わない関数の呼び出しが右オペランドに含まれている場合、ルール チェッカーは違反を報告しません。チェッカーは、次のような単純な操作のみを実行する関数を純粋な関数と見なします。

  • 非 volatile パラメーターまたはグローバル変数の読み取り。

  • ローカル変数への書き込み。

単純な操作の他に、関数に別の関数への呼び出しが含まれている場合、チェッカーは呼び出された関数が純粋な関数であるかどうかの判別を試みます。呼び出された関数が純粋な関数である場合、チェッカーはこの情報を伝播し、(呼び出し元関数の他の操作が単純な操作である限り) 呼び出し元関数に純粋な関数としてタグを付けます。

ルール チェッカーは、次のいずれかを実行する関数を純粋な関数と見なしません。

  • グローバル変数への書き込みまたはパラメーターのデリファレンス

  • volatile 変数の読み取りまたは書き込み、または asm ブロックが含まれている

関数が純粋であるかどうかを判別するため、チェッカーは関数定義を解析する必要があります。チェッカーは関数呼び出しと同じ翻訳単位内でのみ関数定義を検索します。翻訳単位とは、ソース ファイルとソースに含まれているすべてのヘッダーです。関数定義が現行の翻訳単位で見つからない場合、チェッカーはこのルールに対する違反を報告しません。

論理演算子 || または && の右側のオペランドが関数ポインターを使用して関数を呼び出す場合、Polyspace® は呼び出された関数に二次的影響があるのかどうかを判断できません。この場合、違反は報告されません。

トラブルシューティング

ルール違反が想定されるものの、Polyspace から報告されない場合は、コーディング規約違反が想定どおりに表示されない理由の診断を参照してください。

すべて展開する

int check (int arg) {
    static int count;
    if(arg > 0) {
        count++;                   /* Persistent side effect */
        return 1;
    }
    else
        return 0;
}

int getSwitch(void);
int getVal(void);

void main(void) {
    int val = getVal();
    int mySwitch = getSwitch();
    int checkResult;

    if(mySwitch && check(val)) {   /* Noncompliant */
    }

    checkResult = check(val);
    if(checkResult && mySwitch) {  /* Compliant */
    }
    
    if(check(val) && mySwitch) {   /* Compliant */
    }
}

この例では、&& 演算子の右オペランドに関数 check() の呼び出しが含まれる場合、ルールに違反します。check() が静的変数 count を変更するため、この関数呼び出しには永続的な二次的影響があります。この変更が発生するかどうかは mySwitch の値によって決まります。

左オペランドに関数呼び出しが含まれていてもルール違反にはなりません。あるいは、ルール違反を回避するため、関数呼び出しの結果を変数に代入します。この変数は、論理演算で関数呼び出しの代わりに使用します。

チェック情報

グループ:
カテゴリ: 推奨

バージョン履歴

R2024b で導入


1 All MISRA coding rules and directives are © Copyright The MISRA Consortium Limited 2021.

The MISRA coding standards referenced in the Polyspace Bug Finder™ documentation are from the following MISRA standards:

  • MISRA C:2004

  • MISRA C:2012

  • MISRA C:2023

  • MISRA C++:2008

  • MISRA C++:2023

MISRA and MISRA C are registered trademarks of The MISRA Consortium Limited 2021.