This is a minor pet peeve of mine that I felt like sharing. Feel free to post a comment if you agree, disagree or have your own pet coding peeve to share with other readers of this blog.
I quite often see .NET code that tests for the value of a Boolean to see whether it’s true or false:
if (booleanVariable == true)
{
…
}
or
If isBooleanFunction() = False Then
…
End If
Now while not strictly incorrect, this style is, at least, redundant: a Boolean is by nature true or false, and testing for equality with another Boolean returns a Boolean.
I personally prefer to use this:
if (booleanVariable)
{
…
}
or
If Not(isBooleanFunction()) Then
…
End If
Now I’m fully aware I’m taking a purist’s perspective on this: when you take a look at the underlying IL created by Visual Studio (something you can do very easily with .NET Reflector 6) there is absolutely no difference in the generated code – the additional test is optimized out - but even if there’s no impact from an efficiency perspective (and the additional source code bytes don’t eat up a huge amount of hard-drive capacity) it just feels inelegant. Sorry.
There are interesting historical reasons for explicit testing, though, which I’d like to mention. Back before C++ had a native Boolean data-type – and this is still true of C – Booleans were represented as integers which would usually be generated by a pre-processor symbol (such as via Win32’s TRUE and FALSE) or by an enumeration (such as ObjectARX’s Adesk::kTrue and kFalse). So you would have to test for equality explicitly:
if (booleanVariable == Adesk::kTrue)
{
…
}
As C’s (and therefore C++’s – but not C#’s) if statement checks for whether the expression passed in is non-zero, it’s in practice probably just fine not to care about the comparison with Adesk::True, but that would make a potentially dangerous assumption about the values of true and false, which isn’t a good idea (things can change, as we’ll see below :-). C# is different: if you try to pass a numeric expression into an if statement the compiler will ask for a Boolean, as that’s the appropriate native type.
So is truth relative or absolute? Here’s an interesting language quirk that can occasional cause the odd, subtle error: most modern languages who provide the concept of mapping Booleans to integers – perhaps because that’s what they use to implement them - work on the principle that false is 0 and true is non-zero, usually defaulting to 1. Visual Basic (prior to .NET) was different (and presumably this is still true of VBA): false was indeed 0 but the default value for true was –1. This quirk was rationalised out at the introduction of VB.NET, but still causes the odd migration problem if code makes the mistake of depending on absolute truth. :-)
Another interesting aside, as you will sometimes come across code like this… when I was writing C++ code regularly, I’d often invert the sides of the equality test to avoid a subtle class of error (this is a technique I learned from a colleague many years ago):
if (Adesk::kTrue == booleanVariable)
{
…
}
The reason for the inversion is that if you happen to omit one of the equals signs (which is quite a common typo to make, especially if you also code in languages that use a single equals sign for testing equality), the C++ compiler will at least tell you there’s an error, as you’re attempting to assign to an r-value (which comes from the fact it typically belongs to the right side of an equation rather than the left… l-values are assignable but not r-values). So as a force of habit I would start with the value we’re checking against, to avoid this problem.
It turns out there’s less risk of hitting this kind of issue if you’re coding in C#, at least (I haven’t checked modern C++ compilers), at least here you get a helpful warning message:
Alright, that’s it for today. Thanks for indulging my little rant and please do post a comment if you have something to add.