Findbugs 警告:整数移位 32 - 这是啥意思?

Posted

技术标签:

【中文标题】Findbugs 警告:整数移位 32 - 这是啥意思?【英文标题】:Findbugs warning: Integer shift by 32 -- what does it mean?Findbugs 警告:整数移位 32 - 这是什么意思? 【发布时间】:2010-11-04 15:13:30 【问题描述】:

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

long a = b << 32 | c

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

代码执行整数移位 超出范围的恒定量 0..31。这样做的效果是使用整数值的低 5 位 来决定改变多少。这 可能不是预期的,并且 它至少令人困惑。

谁能解释一下上面的具体是什么意思?

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

【问题讨论】:

【参考方案1】:

已编辑:这个问题几乎肯定源于“b”是“int”而不是“long”这一事实。

在C语言中,如果'b'是一个整数而不是一个long并且你左移32位,原始值的所有位都被删除了,所以整体表达式的结果是一样的作为 'c' 你会调用未定义的行为,所以任何结果都是允许的。 Java 对事物的定义不同——正如 Rasmus Faber 的评论和选择的答案中所指出的那样——并且会以可以移动的最大位数为模进行超长移位。 [这似乎是一种奇怪的经商方式;我可能已经用有它们的语言安排了一个例外。但是,它是明确定义的,这比定义的确切含义更重要。] 在计算表达式时不会发生对 64 位的强制;它发生在表达式完成并发生赋值时。

对 5 位的引用是……很有趣。这意味着如果您左移 48 或二进制 110000,则与左移 16 相同。或者,“x &lt;&lt; n”与“x &lt;&lt; (n % 32)”相同。

【讨论】:

你答案的第一部分不正确。在 Jave 中,b 更正:在 C 中,当使用超出范围 [0, typewidth - 1] 的参数移动值时,行为是 undefined。例如,来自 nvidia 和 intel 的 opencl 编译器为表达式 'b >> 32' 提供了不同的行为。 &lt;long&gt; &lt;&lt; 64 有同样的问题 :(【参考方案2】:

来自Java Language Specification:

如果左侧操作数的提升类型是 int,则只有右侧操作数的五个最低位用作移位距离。就好像右手操作数经过位逻辑与运算符 & (§15.22.1) 与掩码值 0x1f。因此,实际使用的移位距离始终在 0 到 31 的范围内,包括 0 到 31。

所以如果 b 是 int,则表达式等同于

long a = b | c;

我非常怀疑这是什么意图。应该是这样的

long a = ((long) b << 32) | c;

(如果 b 已经很长,代码是正确的,FindBugs 对 bug 有误)。

【讨论】:

那么,int &gt;&gt; 32(0x100000) == int &gt;&gt; 0(0x00000)? 你使用的奇怪的伪语法,但是是的,就是这样。

以上是关于Findbugs 警告:整数移位 32 - 这是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法忽略单个 FindBugs 警告?

如何抑制字段或局部变量的 FindBugs 警告?

修复此“从实例方法写入静态字段”findbugs 警告的最佳方法是啥?

FindBugs 警告:使用 keySet 迭代器而不是 entrySet 迭代器效率低下

PMD 和 FindBugs 有啥区别?

findbugs教程