Findbugs警告:32による整数シフト—どういう意味ですか?
質問
Findbugsを使用してサードパーティのソースコードをスキャンし(それに統合する前に注意が必要です)、次の警告が見つかりました:
long a = b << 32 | c
バグ:32パターンIDによる整数シフト: ICAST_BAD_SHIFT_AMOUNT、タイプ:BSHIFT、 カテゴリ:正確性
コードは整数シフトを実行します 範囲外の一定量 0..31。これの効果は、整数値の下位5ビットを使用することです シフトする量を決定します。この おそらく期待されていたくない、と 少なくとも紛らわしい。
上記の意味を正確に説明してください。
ありがとう! (私はJavaプログラミングの初心者です)
解決
Java言語仕様から:
左側のオペランドの昇格された型がintの場合、右側のオペランドの下位5ビットのみがシフト距離として使用されます。右側のオペランドがビット単位の論理AND演算子&amp;を受けたようです。 (&#167; 15.22.1)マスク値0x1fしたがって、実際に使用されるシフト距離は、常に0〜31の範囲にあります。
bがintの場合、式は次と同じです
long a = b | c;
これは、意図されていることです。おそらく
long a = ((long) b << 32) | c;
(bが既に長い場合、コードは正しく、FindBugsはバグについて間違っています)。
他のヒント
編集済み:この問題はほぼ確実に、「b」が「int」であり「long」ではないという事実に起因しています。
Cでは、 'b'がlongではなく整数で、32ビット左にシフトすると、元の値のすべてのビットが削除されるため、式全体の結果は同じになります。 'c' の場合、未定義の動作を呼び出すため、結果はすべて許容されます。 Javaは物事を異なる方法で定義します&#8212; Rasmus Faberのコメントと選択された回答に記載されているように&#8212;また、シフト可能なビットの最大数を法として、長すぎるシフトを行います。 [ビジネスを行う奇妙な方法のようです。私はおそらくそれらを持っている言語で例外を用意したでしょう。ただし、それは明確に定義されており、定義が何であるかよりも重要です。]式が評価されている間、64ビットへの強制は発生しません。式が完成して割り当てが行われたときに発生します。
5ビットへの参照は...興味深いものです。これは、たとえば48またはバイナリ110000だけ左にシフトする場合、左に16シフトするのと同じことを意味します。あるいは、 ' x&<; < n
'は' x&lt;&lt;と同じです。 (n%32)
'。