2012-03-13 17 views
6

左オペランドがfalseの場合、論理&&演算子の短絡が発生します。これは、1つのオペランドがfalseの場合、結果もfalseであることがわかっているためです。なぜビットワイズ&演算子は短絡していませんか?

なぜビット単位の&演算子も短絡していませんか?左のオペランドが0の場合、結果は0であることがわかります。これを(C、Javascript、C#)でテストしたすべての言語は、最初のオペランドの後で停止するのではなく、両方のオペランドを評価します。

オペアンプを短絡させると悪い考えがある理由はありますか?そうでない場合、なぜほとんどの言語がそれを短くするのではないのですか?それは明らかな最適化のようです。

+1

理由の1つは、関数呼び出しの副作用を許容することです。 –

+3

ビット演算子は通常、整数オペランドのビット演算(通常は単一のマシン命令に対応します)のために使用されるため、まれな0の場合を検査するための追加の条件を導入する最適化以外のものになります。乗算が0で短絡しないのはなぜですか?これは、単一の機械命令に対応する単純な算術演算であり、0オペランドの乗算をチェックすることはないでしょうか? –

+0

ビット操作の '|'演算子は、左のオペランドが '0xFFFFFFFF'の場合に短絡する可能性があります。 –

答えて

9

ソース言語のビット単位andは、通常、プロセッサによって実行されるビット単位のand命令に直接変換されるためです。これは、順番に、ハードウェアに適切な数のandゲートのグループとして実装されます。

ほとんどの場合、ほとんどのものを最適化するとは思われません。 2番目のオペランドを評価することは、通常、評価する必要があるかどうかを調べるためにテストするよりもコストがかかります。

+1

第2オペランドに高価な計算が含まれていれば有益です。 –

+3

@PeterOlsonはい、まれにしか左オペランドが0です。ここでは整数について言及していますが、整数値0はブール値の 'false'よりもはるかに希です(ただし、他の番号)。 –

2

通常、ビット単位の演算は非常に安価であるため、チェックによって2倍以上の演算が行われますが、論理演算子を短絡することによる利得は非常に大きい可能性があります。

2

コンパイラが両方のオペランドのチェックを&のように発行しなければならない場合は、NORMAL状態では非常に遅くなるでしょう。

7

短絡は最適化デバイスではありません。これは制御フローデバイスです。 p != NULL && *p != 0の短絡に失敗した場合、わずかに遅いプログラムは得られません。クラッシュするプログラムが発生します。

このような短絡は、ビット単位の演算子ではほとんど意味がありません。は、通常の非短絡演算子よりも高価です。

+1

この議論は私には逆のようです。短絡は、最適化として存在する*ため、フロー制御デバイス*として使用できます。 '&&'が短絡しなかった場合、このようなコードは書くことができませんでした。それは2つの別々のテストでなければなりません。しかし、私はビット単位の短絡が実際には非常に稀であるため、長期的にはおそらくより高価になることに同意します。それはすべて、呼び出しコードの文脈における左オペランドの0値の可能性に依存する。 –

+0

@QuinnTaylor Optimizationは定義上、パフォーマンスにのみ影響し、意味はありません。そのようなコードは、このようなコードを記述するのが自然であり、代替案は扱いにくいので、書くことができます。もし&&が短絡しなければ、おそらく言語は消滅し、使用するのが厄介なものに置き換えられます。 –

1

*は、最初のオペランドが0の場合に短絡しないのと同じ理由で、わかりにくい特別なケースであり、特別なランタイムテストを追加すると、すべての乗算が遅くなります。

オペランドが定数でない場合、短絡は短絡しない場合よりも高価です。したがって、プログラマが明示的に要求しないかぎり、短絡は不要です。だからあなたは本当にいつ起こるかについてきれいで簡単なルールを持っていたいと思っています。

関連する問題