Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is this ternary conditional expression executed?

int x = 5,y = 10;
bool boolean = 0;
int k = (boolean ? ++x, ++y : --x, --y);
cout<<k;

When boolean is 0,it outputs 9, however when it is 1 it outputs 10.I know this is happening because of precedence but cannot exactly figure out how is it happening, please help me understand this.

NOTE:I know I can get the expected output if I use parenthesis,or better write a clean code,I am just using this to understand how compiler would evaluate expressions like these according to precedence.

like image 686
Karan Joisher Avatar asked Feb 26 '16 15:02

Karan Joisher


3 Answers

, has lower precedence than ?:. Which means that the full parenthesising is:

int k = ((boolean ? (++x, ++y) : --x), --y);

As you can see, k is always initialised to the value of --y. It's just that if boolean is true, ++y happens before that.


When looking for the full parenthesis form of an expression, think of it as constructing the expression tree (where the lowest-precedence operator is at the root).

Find the lowest-precedence operator in an expression, and parenthesise its left-hand side argument and its right-hand side argument. Repeat recursively within the sub-expressions just parenthesised.

like image 119
Angew is no longer proud of SO Avatar answered Sep 21 '22 17:09

Angew is no longer proud of SO


Due to the comma operator having the lowest operator precedence, your statement is actually equal to

k = (boolean ? (++x, ++y) : --x), --y;

That means when boolean is true you both increase and decrease y. The result of the ternary expression is thrown away in both cases and k is only assigned the result of --y.

It should be noted that this is not undefined behavior, as the comma operator introduces a sequence point.


To get the result you expect, you need to do

k = boolean ? (++x, ++y) : (--x, --y);

Note that the parentheses around ++x, ++y is strictly not needed, but it does make the expression clearer.

like image 34
Some programmer dude Avatar answered Sep 24 '22 17:09

Some programmer dude


Given the above excellent answers, one should write instead:

if (boolean) {
     ++x;
     ++y;
} else {
     --x;
     --y;    
}
int k = y;

Because then the code is more readable and clear in its intent. This will help anyone who has to maintain the code (including the original author!) without anyone having to waste time by asking SO questions or worrying about the precedence of , or ?: or what the logistics of assignment to such a complex expression are. Any modern compiler will optimize both this and the above to the same resulting code

like image 35
Paul Evans Avatar answered Sep 21 '22 17:09

Paul Evans