Archive
Gotcha: use parentheses around ternary op conditional expressions
Just came across the following case in C# that puzzled me momentarily, especially since the strings involved were long enough and the expression was broken on multiple lines:
bool flag = true;
string test1 = flag? "xa" : "xb";
string test2 = "x" + (flag? "a" : "b");
string test3 = "x" + flag? "a" : "b";
The test3 case fails since the compiler tries to evaluate the "x" + flag expression at the left side of the operator ?, complaining that it cannot implicitly convert string to bool.
e.g I accidentally produced the following wrong code while I was trying to refactor some third-party code to make it more readable:
string test3 = “some long string here” +
(someFlag)?
“some other long string”
:
“some alternative long string”;
whereas the correct was:
string test3 = “some long string here” +
( (someFlag)?
“some other long string”
:
“some alternative long string” );
The correct one needs the whole conditional expression enclosed in parentheses. In fact, the parentheses around (someFlag) can be skipped. In usually prefer them visually, even when I use just a boolean variable instead of a more complex boolean expression, but in case like this one the x + (someFlag)? a : b can be confusing to the reader of the code, not seeing x + (someFlag) will be treated as the conditional instead of someFlag.
Luckily the C# compiler is deterministic enough and not trying to imply meaning from one’s wrong syntax. Had it been some futuristic AI-based interpreter, well, it might have gotten confused there too.
To avoid this confusion in the first place, probably one could have designed a (bool)?x:y operator instead with parentheses being required around the boolean expression, but people coming from other languages (say C++) might then end up writing bool && (bool)?x:y and expect the condition to be bool && (bool) instead of just (bool), so even that syntax would be problematic.
Speaking of other languages, quoting from Wikipedia article on ternary operator:
C++
Unlike in C, the precedence of the
?:
operator in C++ is the same as that of the assignment operator (=
orOP=
), and it can return an lvalue. This means that expressions likeq ? a : b = c
and(q ? a : b) = c
are both legal and are parsed differently, the former being equivalent toq ? a : (b = c)
.
So confusion even between languages that share a C-style syntax might not be avoided.