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 << n
”与“x << (n % 32)
”相同。
【讨论】:
你答案的第一部分不正确。在 Jave 中,b 更正:在 C 中,当使用超出范围 [0, typewidth - 1] 的参数移动值时,行为是 undefined。例如,来自 nvidia 和 intel 的 opencl 编译器为表达式 'b >> 32' 提供了不同的行为。<long> << 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 >> 32(0x100000) == int >> 0(0x00000)
?
你使用的奇怪的伪语法,但是是的,就是这样。以上是关于Findbugs 警告:整数移位 32 - 这是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章
修复此“从实例方法写入静态字段”findbugs 警告的最佳方法是啥?