9

Why this statement :

int a = 7, b = 8, c = 0; c = b>a?a>b?a++:b++:a++?b++:a--; cout << c; 

is not equal to :

int a = 7, b = 8, c = 0; c = (b>a?(a>b?a++:b++):a++)?b++:a--; cout << c; 

and is equal to :

int a = 7, b = 8, c = 0; c = b>a?(a>b?a++:b++):(a++?b++:a--); cout << c; 

Please give me some reason. Why ?

4
  • 4
    cppreference.com/wiki/operator_precedence Commented May 9, 2010 at 11:52
  • 31
    Jesus Christ, why would you ever want to write code like that?! Commented May 9, 2010 at 11:52
  • You should write the code nicely with brackets unless you know the precedences Commented May 9, 2010 at 12:08
  • 2
    s/unless you know the precedences//. This code would be a pain for anyone to understand, even someone intimately familiar with precedence, associativity, and all that. Better to split it into multiple lines and use if statements. Commented May 9, 2010 at 12:26

3 Answers 3

15

Because ? : is right-to-left associative. It's defined like that in the language.

Sign up to request clarification or add additional context in comments.

1 Comment

You know, I think you're right and I'm wrong. I'm going to delete mine.
7

I believe @sth has provided the correct answer, however, I think @Skilldrick got it right on the comments - why the hell would you ever write something like that.

As well as the precedence issue, you really need to be careful when incrementing the same variables in a single statement. There may or may not be sequence points in the statement, and therefore the order of evaluation of the increments might not be guaranteed. You could end up with different results with different compilers or even different optimization settings on the same compiler.

9 Comments

Absolutely - multiple increments of the same variable at the same sequence point is the dreaded undefined behaviour. That line could probably legally be equal to either of those.
The order of a ? b : c is guaranteed.
I may be mistaken, but isn't ?: one of those operators who does guarantee the order of evaluation and does have sequence points between evaluating operands (others are ,, &&, || and perhaps some others)?
Isn't the real answer to this question phimuemue's one on operator precedence? There's no code branch in this where or b are incremented twice is there?
@Neil, is the greediness of the matching of ? with : defined? I thought that was one of those "why the hell would you do that" sort of things.
|
1

The operators &&, ||, and ?: perform flow control within expressions. ?: behaves like an if-else statement.

c = b>a?a>b?a++:b++:a++?b++:a--; if ( b>a ) if ( a>b ) a ++; else b ++; else if ( a ++ ) b ++; else a --; b>a? ( a>b ? a ++ : b ++ ) : ( a ++ ? b ++ : a -- ) 

The associativity is necessary to have behavior like if … else if … else.

Sometimes I use an expression similar to yours for lexicographic sequence comparision:

operator< ()( arr &l, arr &r ) { return l[0] < r[0]? true : r[0] < l[0]? false : l[1] < r[1]? true : r[1] < l[1]? false : l[2] < r[2]; } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.