私がこのような状態にある場合:
if (X && Y) {}
コンパイラはfalseかどうY
かをチェックしますか?X
コンパイラに依存しますか?
C仕様(6.5.13)は、この点を明確にしています。
4ビット単位の二項&演算子とは異なり、&&演算子は左から右への評価を保証します。第2オペランドが評価される場合、第1オペランドと第2オペランドの評価の間にシーケンスポイントがあります。最初のオペランドが0と等しい場合、2番目のオペランドは評価されません。
したがって、C言語自体は、その場合X == 0
はY
チェックされないことを定義しています。
がY
チェックされているのX
はtrue
X
falseの場合Y
、チェックされません
ところで、チェックはコンパイルフェーズではなく実行ランタイムで行われます。
&&
とは||
左から右への評価を強制します。どちらも、第2オペランドが評価される場合、第1オペランドと第2オペランドの間にシーケンスポイントを導入します。式の結果が第1オペランドのみから決定できる場合、どちらも第2オペランドを評価しません。のIOWは、X && Y
がfalseのY
場合は評価されませんが、のはtrueの場合は評価されません。 X
X || Y
Y
X
優先順位は評価の順序に影響しないことに注意してください。のような式が与えられた場合X || Y && Z
、 。よりも優先順位が高くても、の前に評価されY && Z
ません。 最初に評価されます。結果が0(false)の場合、評価されます。その結果がゼロ以外(true)の場合、評価されます。 X
&&
||
X
Y
Z
これは、言語標準(2011バージョン、オンラインドラフト) のセクション6.5.13および6.5.14で定義されているため、コンパイラに依存しません。
Y
に副作用がある場合、またはそれにアクセスすることが未定義の動作(たとえば、不正なポインタの逆参照)である可能性がある場合、コンパイラは、trueと評価されない限り、それが評価されないようにする必要がY
ありX
ます。ただし、両方X
とY
に副作用がなく、コンパイラがそれらへのアクセスが明確に定義されていることを認識している場合は、両方のアクセスが発生するように最適化することを選択できます。