Findbugs警告:32による整数シフト—どういう意味ですか?

StackOverflow https://stackoverflow.com/questions/1023373

  •  06-07-2019
  •  | 
  •  

質問

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) '。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top