Archive

Posts Tagged ‘Expressions’

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 (= or OP=), and it can return an lvalue. This means that expressions like q ? a : b = c and (q ? a : b) = c are both legal and are parsed differently, the former being equivalent to q ? a : (b = c).

So confusion even between languages that share a C-style syntax might not be avoided.

Advertisements
%d bloggers like this: