web-dev-qa-db-ja.com

論理積、OR:左から右への評価は保証されていますか?

論理演算子(_&&_ _||_)の左から右への評価は保証されていますか?

私がこれを持っているとしましょう:

_SDL_Event event;

if (SDL_PollEvent(&event)) {
    if (event.type == SDL_QUIT) {
            // do stuff
    }
}
_

これはこれと同じであることが保証されていますか?

_SDL_Event event;

if (SDL_PollEvent(&event) && event.type == SDL_QUIT) {
    // do stuff
}
_

これも非常に重要です。たとえば、abの2つの要件があるとします。要件aは、bよりも失敗する可能性がはるかに高くなります。その場合、if (a && b)よりもif (b && a)と言う方が効率的です。

29
orlp

はい、保証されています。そうしないと、そのような演算子はその有用性の多くを失うことになります。

重要なお知らせ:これは有効ですのみ組み込みの_&&_および_||_の場合。一部の犯罪者がそれらをオーバーロードすると、それらは「通常の」オーバーロードされた二項演算子として扱われるため、この場合両方のオペランドは常に評価され、通常どおり不特定の順序で行われます。このため、それらを過負荷にしないでください。プログラムの制御フローに関する非常に重要な仮定を破ります。


関連する標準見積もり

ビルトイン_&&_および_||_は短絡動作を保証しています

§5.14¶1

_&_とは異なり、_&&_は左から右への評価を保証します。最初のオペランドがfalseの場合、2番目のオペランドは評価されません。

§5.15¶1

_|_とは異なり、_||_は左から右への評価を保証します。さらに、第1オペランドがtrueと評価された場合、第2オペランドは評価されません。

過負荷の場合、それらは「通常の」二項演算子として動作します(短絡や評価の順序の保証はありません)

§13.5¶9

13.5.3項から13.5.7節で明示的に言及されていない演算子は、13.5.1または13.5.2の規則に従って、通常の単項および二項演算子として機能します。

および_&&_および_||_はこれらの節で明示的に言及されていないため、通常の§13.5.2が成り立ちます。

§13.5.2¶1

二項演算子は、1つのパラメーターを持つ非静的メンバー関数(9.3)、または2つのパラメーターを持つ非メンバー関数のいずれかによって実装されます。したがって、任意の二項演算子_@_の場合、_x@y_はx.operator@(y)またはoperator@(x,y)のいずれかとして解釈できます。

片側のみまたは特定の順序で評価するための特別な規定はありません。

(C++ 11標準からのすべての引用)

43
Matteo Italia