Findbugs warning: Integer shift by 32 — what does it mean?

后端 未结 2 492
礼貌的吻别
礼貌的吻别 2020-12-03 09:03

I was scanning a third party source code using Findbugs (just to be cautious before integrating into it mine), and found the following warning:

long a = b &l         


        
相关标签:
2条回答
  • 2020-12-03 09:23

    From the Java Language Specification:

    If the promoted type of the left-hand operand is int, only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (§15.22.1) with the mask value 0x1f. The shift distance actually used is therefore always in the range 0 to 31, inclusive.

    So if b is an int, the expression is identical to

    long a = b | c;
    

    which I highly doubt is what is intended. It should probably have been

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

    (If b is already a long, the code is correct and FindBugs is mistaken about the bug).

    0 讨论(0)
  • 2020-12-03 09:32

    Edited: The problem almost certainly stems from the fact that 'b' is an 'int' and not a 'long'.

    In C, if 'b' is an integer instead of a long and you shift left by 32 bits, all the bits from the original value have been removed, so the result of the overall expression would be the same as 'c' you would invoke undefined behaviour, so any result is permissible. Java defines things differently — as noted in the comment by Rasmus Faber and the chosen answer — and does overlong shifts modulo the maximum number of bits that can be shifted. [It seems an odd way to do business; I'd probably have arranged for an exception in a language that has them. However, it is clearly defined, which is more important than exactly what the definition is.] The coercion to 64-bits doesn't occur while the expression is evaluated; it occurs when the expression is complete and the assignment happens.

    The reference to 5 bits is ... intriguing. It means that if you shift left by, say, 48, or binary 110000, it is the same as shifting left by 16. Or, alternatively, 'x << n' is the same as 'x << (n % 32)'.

    0 讨论(0)
提交回复
热议问题