メインコンテンツ

CWE Rule 783

Operator Precedence Logic Error

R2023a 以降

説明

The program uses an expression in which operator precedence causes incorrect logic to be used.

Polyspace 実装

このルール チェッカーは、[演算子の優先順位のルールにより、予期せぬ式の評価が得られる可能性があります] をチェックします。

すべて展開する

問題

この問題は、演算子の優先順位ルールで決定される評価順が予想外であるために演算式の結果が想定を外れる可能性がある場合に発生します。

欠陥によって、x op_1 y op_2 z という形式の式が強調表示されます。ここで、op_1 および op_2 はこのエラーをよく引き起こす演算子の組み合わせです。たとえば、x == y | z です。

チェッカーは、すべての演算子の組み合わせにフラグを設定するわけではありません。たとえば、x == y および z の間で論理 OR の実行を意図する可能性は非常に高いため、x == y || z にはフラグを設定しません。具体的には、チェッカーは以下の組み合わせにフラグを設定します。

  • && および ||: たとえば、x || y && zx && y || z

  • 代入演算とビット演算: たとえば、x = y | z です。

  • 代入演算と比較演算: たとえば、x = y != zx = y > z

  • 比較演算: たとえば、x > y > z (いずれかの比較が等号である場合 x == y > z を除く)。

  • シフト演算と数値演算: たとえば、x << y + 2 です。

  • ポインターのデリファレンスおよび演算: たとえば、*p++ です。

リスク

欠陥により、次のような問題が発生する場合があります。

  • コード レビュー担当者がコードをレビューする場合に、意図されている評価順がすぐにはわからない。

  • 評価の結果が予想と一致しない可能性がある。次に例を示します。

    • 演算 *p++ では、デリファレンスされた値がインクリメントされるとの予想が可能。しかし、ポインター p はデリファレンスの前にインクリメントされている。

    • 演算 (x == y | z) では、xy | z と比較されるとの予想が可能。しかし、== 演算は | 演算の前に行われている。

修正方法

評価の順序が想定どおりであるかどうかを確認します。違っている場合は、小かっこを適用して望ましい評価順を実装します。

コードの可読性を高めるため、演算子の優先順位ルールにより評価順が強制される場合でも、小かっこを適用してその評価順を実装することをお勧めします。

例 — 想定外の評価順になる可能性がある式
int test(int a, int b, int c) {
    return(a & b == c);  //Noncompliant
}

この例では、まず == 演算が、続いて & 演算が行われます。逆の順序の演算が想定されていた場合、結果は予想と異なったものになります。

修正 — 想定どおりの順序にするための小かっこ

1 つの修正方法として、小かっこを適用して想定された評価順を実装します。

int test(int a, int b, int c) {
    return((a & b) == c);
}

チェック情報

カテゴリ: Behavioral Problems
PQL 名: std.cwe_native.R783

バージョン履歴

R2023a で導入