20 Apr 2006, 04:54

The exciting world of operator precedence

I think it’s time we had a talk about operator precedence. Specifically operator precedence in C++ as it pertains to the bitwise “and” and “or” operators (& and |). (Ok, and let’s not forget the all too often overlooked “xor” (^)) One thing that it seems that people occasionally forget is that these operators are evaluated at a lower precedence than the comparison operators, such as == and !=. This means that the following piece of code doesn’t do what you might have assumed it would:

if (bitmap & BIT_MASK != 0)
{
...
}

Unless, of course, you correctly assumed that it would first compare BIT_MASK to see if it is not 0 (which likely is true) and then performs a bitwise “and” of the result of that comparison and the bitmap variable. Not the intended result at all. For this to work you would need to group the bitwise portion of the expression using parentheses (which also happen to be at the highest level of operator precedence) like so:

if ((bitmap & BIT_MASK) != 0)
{
...
}

(Of course the comparision to 0 is completely unnecessary in this example, but hey, it’s just an example.) This isn’t anything groundbreaking, in fact it’s pretty basic stuff. Still, given the fact that I’ve seen this several times as the root cause of defects I’ve fixed makes it seem like maybe this gets overlooked too frequently. I wonder if it may be due to the fact that the bitwise operations feel more like arithmetic operators such as + and – which do have a higher precendence than the comparison operators. It’s always a good idea to pay close attention to how your expressions will be evaluated and not just assume that things will be grouped the way you intuitively feel they would. And of course it’s an even better idea to actually step through your code and see just how that expression evalutes for different possible values of the variables, which would have caught something like the above mistake trivially.

Comments

Comment by Neal on 2006-04-20 07:52:28 +0000

I usually avoid precedence problems by blasting parentheses all over anything that is even remotely ambiguous in my mind.

Maybe I’m just being lazy to not learn the precedence tables, but I tell myself that I’m “increasing my code readability”.

Comment by Phil on 2006-04-20 11:45:28 +0000

I must say, I only understood about 34 of that, since I don’t code myself. But, seeing as how I’m writing a book with a coder as the protagonist, it’s nice to see a bit of ACTUAL C++ being thrown around (as opposed to the fake kind).

I think it’d be fun to learn C++, but sadly, I will settle for AppleScript at the moment.

Comment by Tobin on 2006-04-20 19:40:50 +0000

I can honestly say, in the past almost 5 years of career software development, I have never used the bitwise AND/OR. And I’ve used the XOR once. Maybe.

Does that make me a bad programmer?

Comment by Will on 2006-04-21 22:58:53 +0000

Yes, yes it does. Ok, no it doesn’t. But never? Really? I don’t use them every day or anything, but they certainly come in handy every now and then.

Comment by Tobin on 2006-04-23 19:21:42 +0000

Yes, really. What do you even use them for? I have a feeling they’re more useful in c++ than java.

Comment by Will on 2006-04-23 19:48:25 +0000

They’re just a convenient, fast, and succinct way to pass around and test for multiple boolean properties or flags at once. Plus if you’re passing things around as a bitmap it can be nice because if you end up needing to add a new property in the future you can just define an enum for the next bit in the bitmap without having to add a new method to the object. Also you tend to work with them a lot more when doing MFC development (I know, painfully outdated) because window properties are often set as bitmaps.

Comment by Posko on 2006-04-27 16:39:28 +0000

Nerd talk!