about:code

Bitwise Operators and Precedence

Posted in Uncategorized by Joseph Gordon on April 16, 2010

I learned something today. I did not enjoy it, but I learned nonetheless. The lesson is on operator precedence with respect to bitwise operators. In C#, consider about the following:

bool x = TestFlags(0x04); // What is x?

public bool TestFlags(uint flags)
{
    return flags & 0x04 != 0;
}

Well, it’s a compile error, that’s what it is. This was completely surprising to me. Specifically, the error is:

Error 3 Operator '&' cannot be applied to operands of type 'uint' and 'bool'

Dude! Wait! What? That means that on one side of the ‘&’ is a uint and on the other, a bool. The only way I could see that happing is if the operator ‘!=’ has precedence over ‘&’. Surely that isn’t right! But au contraire, after some googling (Ah teh Google, how I love thee) I discovered that indeed, ‘!=’ has precedence over ‘&’! This fact disagreed completely with my mental model.

After much griping to my coworkers, I started wondering why this was the antithesis of my mental model. I think it’s because of the difference between the precedence of the operators ‘+’ and ‘&’ with respect to operator ‘!=’ or ‘==’. To clarify:

flags & 0x04 != 0 ≡  flags & (0x04  != 0)
flags + 0x04 != 0 ≡ (flags +  0x04) != 0)

Right, wrong, or indifferent that dichotomy is why I was initially confused. I also wander, “How much C/C++ has a logical bug because of this subtlety?” Let’s take a look at that code again:

bool x = TestFlags(0x04); // What is x?

public bool TestFlags(uint flags)
{
    return flags & 0x04 != 0;
}

With C/C++, it compiles without the need for parenthesizes and x is 0. Of course, in the C++ world an int is automatically cast to a bool and in a C world there is no difference. Therefore, there would be no need to add the ‘!=’ or ‘==’ to the statement. However, will the likelihood of seeing this faux pas increase as younger generations of programmers hit the streets with only higher level language experiences?