July 26, 2009, 11:50 p.m.
IT

Subtle bugs in Java

I recently uncovered a bug that troubled me for about 30 minutes. This bug was introduced in the Javaconfig framework, as I was extending support for more overloaded methods by "copying the pattern". But it proved that in this case, following a pattern does not always work.

Inductive reasoning states that if element 1 is the same as 2 and 3 and 4 and ... n, element n+1 will most probably be the same as well. However inductive reasoning is rather evil when writing software as it is not mathematically sound.

Here is the code - spot the problem:

public static long setBit(long pValue, int pBitPosition) {
   return pValue |= 1 << pBitPosition;
}

The problem with this code is due to auto type conversion - stuff that happens behind the scenes. In this case, the code fragment (1 << pBitPosition) can be written in type form as (int32 << int32) which results in an int32. But - we are bitwise OR-ing an int32 with an int64, which will break the moment pBitPosition exceeds 31. The solution is simple, but it requires us to break the pattern (this method was copied from byte, char, short, int):

public static long setBit(long pValue, int pBitPosition) {
   return pValue |= 1L << pBitPosition;
}