Bitwise Operators and Precedence
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?
leave a comment