Findbugs警告:整数移位32 – 这是什么意思?

我正在使用Findbugs扫描第三方源代码(只是为了在集成到我之前要小心),并发现以下警告:

long a = b << 32 | c 

错误:整数移位32模式ID:ICAST_BAD_SHIFT_AMOUNT,类型:BSHIFT,类别:正确性

代码在0..31范围之外执行整数移位恒定量。 这样做的结果是使用整数值的低5位来决定移位多少。 这可能是不希望的,它至少令人困惑。

谁有人可以解释一下上面究竟是什么意思?

谢谢! (我是Java编程的新手)

从Java语言规范 :

如果左侧操作数的提升类型是int,则只使用右侧操作数的五个最低位作为移位距离。 就好像右手操作数受到按位逻辑AND运算符&(§15.22.1)和掩码值0x1f的影响。 因此,实际使用的移位距离始终在0到31的范围内,包括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以不同的方式定义 – 正如Rasmus Faber的评论和所选答案中所指出的那样 – 以超长移位模数可以移位的最大位数。 [做生意似乎很奇怪; 我可能已经安排了一个包含它们的语言的例外。 但是,它是明确定义的,这比定义的确切更重要。]在表达式被评估时,不会发生64位的强制; 它在表达式完成并且赋值发生时发生。

对5位的引用是……有趣的。 这意味着如果向左移动,比如48,或二进制110000,则与向左移动16相同。或者,’ x << n '与' x << (n % 32) ”。