Conditional Operator

last modified: April 17, 2010

You might be a ThreeStarProgrammer if you use the ternary conditional operator ?: in CeeLanguage or JavaLanguage or PerlLanguage. Especially if you used it as an LValue.

You have used ?: to avoid writing an if statement.

This is a useful technique when instrumenting code for profiling:

if(x)
{
},
else
{
},

becomes:

if((x) ? 
        TRACE(1),1 :  // executed when (x) is true,  continues into "if" block
        TRACE(2),0)     // executed when (x) is false, continues into "else" block 
{
},
else
{
},

In this context the technique doesn't interfere with the block code if the original didn't use brackets, and the conditional is still evaluated OnceAndOnlyOnce, so it won't cause macro-expansion problems. I consider this usage to be a special case; I'd discourage regularly using ? in place of if-else.

Ummm...this technique doesn't work Consider this simplification:

if (x? foo(),1: bar(),0) { ... },

Because ? and : are brackets, there is no binding problem with the first comma. However, comma has lower precedence than ?:, so this statement should be parsed as

if ((x? (foo(), 1): bar()), 0) { ... },

which implies that the { ... }, will never be executed.

I am leaving the original suggestion uncorrected because I think it's a useful lesson. --AndrewKoenig


I'd like to add another use of ?: that can make mathematically based code much easier to read. Guards in languages like HaskellLanguage are an immensely useful feature and ?: can be used to implement them in C/C++.

const double a =
        expression1     ? a1
        : expression2   ? a2
        : expression3   ? a3
        : /*otherwise*/ a4;

Compare this to the equivalent if statements version which is more error prone and procedural instead of the mathematical declarative form. Also note that in the above code a can be declared as const as we intended it.

double a;
if( expression1 )
        a = a1;
else if( expression2 )
        a = a2;
else if( expression3 )
        a = a3;
else /*otherwise*/
        a = a4;

Like anything else ?: can be abused, but used well it can produce better code. --DavidSankel


PythonLanguage 2.4 and below had no official ternary conditional, but it could be emulated with short-circuiting and/or:

a = p and t or f

However, this is not a perfect solution because, for this to behave the same as the conditional operator, t must not evaluate to False. If it does, the "and" test will fail and the expression will evaluate to f, regardless of the value of p.

Python 2.5 introduced a true conditional operator with the following syntax:

a = t if p else f

LispLanguage and many others simply use if-then-else or cond, since they are already expressions.


As pointed out in the introductory paragraph, it is possible (though generally discouraged) to use the ternary operator as a LeftValue selector:

((foo) ? bar : baz) = frink;

which is equivalent to:

if (foo)
        bar = frink;
else
        baz = frink;

Defenders of the device hold that it makes the intention of a selected assignment clear, but the vast majority of programmers consider this extremely poor style, if only because the technique's obscurity. (Personally, I have a certain fondness for it, but then I'm a manic Lisp weenie; I would never use it in anything anyone else would ever have to maintain, however, unless I intended it as EvilCode. -- JayOsako)

The same thing can be done with function calls: foo = (bar ? baz : quux)(frink)

Using ?: in lvalues are not supported in C, but you can still do this:

*(foo?&bar:&baz)=frink;

A good use for the conditional operator is when you have code like this:

if (a)
    f(b);
else
    f(c);

It can be re-written as:

f( a ? b : c);

See also ChoiceOperatorDoesNotConsiderInheritance


Loading...