EXP13-C. 関係演算子および等価演算子は、結合則が成り立たないものとして扱う
C では、関係演算子および等価演算子は左結合である。他のプログラミング言語とは異なり、関係演算子や等価演算子を連鎖させることができる。C 標準 [ISO/IEC 9899:2011] セクション 6.5.8 の脚注 107 には次のように記載されている。
式
a<b<c
は、通常の数学的な意味のようには解釈されない。構文が示しているように、(a<b)<c
を意味している。言い換えれば、"a
がb
より小さい場合は 1 とc
を比較し、それ以外の場合は 0 とc
を比較する" ということである。
これらの演算子は左結語であり、一番左の比較が最初に実行され、結果が一番右の比較と比較される。そのため、プログラマは (特に条件として使用される式で) 解釈間違いを招きやすい式を書く可能性がある。
違反コード
以下のコード例は問題なくコンパイルできるが、プログラマが本当に意図したコードを意味する可能性は低い。
int a = 2; int b = 2; int c = 2; /* ... */ if (a < b < c) /* 誤解を招きやすい */ /* ... */ if (a == b == c) /* 誤解を招きやすい */
a < b < c
は真と評価される。プログラマの意図は偽と評価されることであろう。a == b == c
は偽と評価される。プログラマの意図は真と評価されることであろう。
適合コード
関係演算子や等価演算子は、連鎖できないものとして扱うべきである。
if ( (a < b) && (b < c) ) /* 意図したものがより明確で、より確実となる */ /* ... */ if ( (a == b) && (a == c) ) /* 同上 */
リスク評価
関係演算子や等価演算子を間違って使用すると、プログラムの間違った制御フローにつながる恐れがある。
ルール |
深刻度 |
可能性 |
修正コスト |
優先度 |
レベル |
---|---|---|---|---|---|
EXP13-C |
低 |
低 |
中 |
P2 |
L3 |
自動検出(最新の情報はこちら)
ツール |
バージョン |
チェッカー |
説明 |
---|---|---|---|
ECLAIR |
1.1 |
exprprns |
実装済み |
GCC |
V. 4.3.5 |
|
|
PRQA QA-C | 8.1 |
3392 |
実装済み |
関連するガイドライン
CERT C++ Secure Coding Standard | EXP17-CPP. Treat relational and equality operators as if they were nonassociative |
参考資料
[ISO/IEC 9899:2011] | Section 6.5.8, "Relational Operators" |
翻訳元
これは以下のページを翻訳したものです。
EXP13-C. Treat relational and equality operators as if they were nonassociative (revision 31)