views:

149

answers:

3

can every if...then...else statement be converted into an equivalent statement using only ?:

+7  A: 

The code:

if ( flag ) {
   exit(1);
}
else {
   return 0;
}

cannot be converted into:

flag ? exit(1) : return 0;

A better example - this would be inside a loop:

if ( flag ) {
   continue;
}
else {
   break;
}

cannot be converted to:

flag ? continue : break;
anon
You could do `return (flag ? exit(1),1 : 0)`, but that's just ugly.
outis
again, won't work if expression evaluates to void
Pavel Radzivilovsky
@Pavel Radzivilovsky Take a look here: http://codepad.org/YU33OrwjIt won't work only if we assign void to some variable, except it work perfectly.
Vitaly Dyatlov
I thought I came up with a method that made the answer yes; then looked at your examples! In the end my advice would be to use the constructs *appropriately* not perversely - which renders the question irrelevant.
Clifford
+1  A: 

No.

Both "branches" of the conditional expression must evaluate to the same type, and that type must not be void.

For example, you could do this:

x > 0 ? printf("Positive!\n") : 0;

because printf return int. (I would only use this in a round of code golf, though; in fact, I just did.)

But you cannot do this:

x > 0 ? exit() : 0;

because exit returns void (or, actually, doesn't return at all).

Thomas
Can't you write a function that returns `int` and that calls `exit(0)` and then returns 0 for example? Then do `x > 0 ? myExit() : 0;`. This will work, so I think the answer is actually "yes, if you have nothing better to do".
IVlad
You could, but it would be pointless. Also, this doesn't work if the if/else statement contains substantial code, instead of just a single statement or two.
DeadMG
Your first point about type and void is only true if you attempt to assign the result of the ?: or use it as an argument. Your second example as it stands compiles and runs in MSVC++2008 at least.
Clifford
@Clifford: Hmm, you're right. Interesting. Is the `0` cast to `void` in that case?
Thomas
@Thomas: It appears to be regarded as simply a null statement. For example `int main(){ 0;}` compiles but generates no code for the 0; statement (or in fact any other unassigned constant expression).
Clifford
+3  A: 

While any use I can think of for the ternary operator can be implemented as an if/else, the converse is not true; at least not without resorting to perverse and pointless 'tricks' that yield no benefit in terms of performance, readability, or maintainability.

The syntax of if/else is:

if( <boolean expression> )
    <statment>|<statment block>
else
    <statment>|<statment block>

whereas the syntax of the ?: ternary operator is:

<boolean expression> ? <expression> : <expression> ;

The important thing here being that an <expression> and a <statement> are different syntactic elements.

The very limited usage of the form:

if( b ) x = y else x = z ;

can be implemented as:

x = b ? y : x ;

but here the restriction is that the same variable is being assigned in both the true and false clauses, (and therefore y and z are both at least convertible to the type of x). So it may be said that any conditional assignment can be implemented with the ternary operator (after all that is its primary purpose).

Now since a function call is a valid expression, you could wrap the true and false clauses in separate functions, but to do that simply to prove a point is somewhat perverse:

if( b )
    true_stuff() ;
else
    false_stuff() ;

is equivalent to:

b ? true_stuff() : false_stuff() ;

and those functions can contain any code at all.

So to convert the more general if/else case to a ?: operation, the true/false statement blocks must first be wrapped in separate functions. However even then Neil Butterworth's examples will defeat this approach since the behaviour of break, continue, and return affect control flow beyond the confines of the if/else construct, (although perhaps those are also examples of code you want to avoid!). The presence of a goto in the if/else would also defeat this approach. .

I think in the end, even if you could, why would you want to?

Clifford