Tuesday, April 7, 2009

Another win for findbugs: is Math.abs broken?

I was wrapping up some code today, and ran into a weirdly interesting findbugs warning: RV_ABSOLUTE_VALUE_OF_HASHCODE.

Bill Pugh has a more in-depth post on his blog from 2006 about this. But, if you've ever written code like:

Object x = bucket[ Math.abs(y.hashCode()) % bucket.length]

you have a bug. Or, maybe it's a bug in Math.abs, depending on your point of view.

You would probably be surprised to learn that Math.abs(Integer.MIN_VALUE) == Integer.MIN_VALUE, but it's true (go ahead and try it out).

So, about one time out of 4 billion, you'll get an ArrayIndexOutOfBoundsException, when your object's hashCode returns Integer.MIN_VALUE, and you end up with a negative array index.

This seems like a fairly common bit of code to write. In fact, back when Bill wrote this post, he uncovered this occurring 7 times in eclipse, 6 times in jboss, and twice in tomcat, among others.

This behavior sort of makes sense when you think about it. There's really no other value Math.abs could return for Integer.MIN_VALUE, and, it is, in fact, documented. Still, I'd bet that this bug exists somewhere in code you are using.

Anyway, it's worth reading Bill's post to check out some suggested fixes, and dig a little deeper into this.

No comments: