Beware of the ?: operator and enclose it in parentheses
This bug was found in Haiku source code.
Incorrect code:
bool IsVisible(bool ancestorsVisible) const
{
int16 showLevel = BView::Private(view).ShowLevel();
return (showLevel - (ancestorsVisible) ? 0 : 1) <= 0;
}
Explanation:
The ternary operator ?: has a very low precedence, lower than that of operations /, +, <, etc.
It is also lower than the precedence of the '-' operator. Forgetting about that may result in an unexpected program behavior.
The programmer thinks that the operations will execute in the following order:
(showLevel - (ancestorsVisible ? 0 : 1) ) <= 0
But the sequence will actually be this one:
((showLevel - ancestorsVisible) ? 0 : 1) <= 0
The code isn't much complicated, is it? That the programmer happened to make a mistake in such simple and short code only proves how dangerous the ?: operator may be. It's very easy to make a mistake when using it. And using the ternary operator in more complex conditions should be treated as pure sabotage. It's not only that you are very likely to make and miss a mistake, it's also that such expressions are very difficult to read.
Correct code:
return showLevel - (ancestorsVisible ? 0 : 1) <= 0;
Recommendation:
In my earlier articles, I would recommend using the ternary operator in simple expressions only. But as the example above proves, programmers tend to make mistakes in short and simple expressions too.
I don't suggest rejecting the ?: operator completely. It may be useful and even necessary sometimes.
So I'd rather recommend doing the following.
ALWAYS enclose the ternary operator in parentheses.
Suppose you have an expression:
A = B ? 10 : 20;
Then you should write it like this:
A = (B ? 10 : 20);
Yes, the parentheses are excessive here.
But it will protect your code later when you or your colleague adds an X variable to 10 or 20 while doing code refactoring:
A = X + (B ? 10 : 20);
Without the parentheses, you could forget that the ?: operator has a low precedence and accidentally break the program.
Subscribe to new hints at: http://eepurl.com/bvZrnf
or read them on http://cpphints.com