C言語についての記事です。論理ANDと論理ORの右項の評価をしない場合があります、という注意喚起です。
2項演算子の評価順序について
論理AND演算子 ‘&&’ は、左項を評価して、それが真の場合のみ右項を評価します。
論理OR演算子 ‘||’ は、左項を評価して、それが偽の場合のみ右項を評価します。
これは、左項の値を評価するだけで式の値が確定する場合があるためです。論理AND演算子の左項が偽であれば右項の評価結果に依存せず式の値は偽になります。同じように論理OR演算子の左項が真であれば式の値は真になります。
このため、論理AND演算子や論理OR演算子の右項に関数呼び出しやインクリメント演算子があっても、実行されない場合があります。
なお、C言語の多くの演算子、例えばビットAND演算子 ‘&’ は、左項と右項のどちらが先に評価されるかは、言語仕様として決まっていません。
どう読める?
次のC言語のコード片を見てください。
int a = 0;
int b = 0;
_Bool c;
c = a && ++b;
/* b is 0 or 1? */
このコード片の場合、論理AND演算子の左項が偽(0)となるため、右項を評価せずに式の値を偽にします(変数 c は、false になります)。このため、変数 b の値は、0 のままです。
コーディングガイドライン
MISRA C 最新版(2023)の Rule 13.5 では、以下の趣旨のガイドラインを紹介しています。
論理AND演算子と論理OR演算子の右辺に副作用を含まないようにしよう
副作用は、関数の呼出や変数の値を書き換える演算子(代入演算子やインクリメント演算子)だと考えてください。
最後に
プログラミング言語によっては、最後まで評価する場合もあります。Wikipediaの「短絡評価」の記事にまとめられています。
C言語を使いこなしていきましょう!