This question already has an answer here:
Well, I had a question about comma in ternary operator. Cut the crap, the code is below:
void test_comma_in_condition(void)
{
int ia, ib, ic;
ia = ib = ic = 0;
bool condition=true;
cout<<"Original:"<<endl;
cout<<"ia: "<<ia<<endl;
cout<<"ib: "<<ib<<endl;
condition?(ia=1, ib=2):(ia=11, ib=12);
cout<<"After:"<<endl;
cout<<"ia: "<<ia<<endl;
cout<<"ib: "<<ib<<endl;
ia = ib = ic = 0;
condition?ia=1, ib=2, ic=3:ib=22,ia=21, ic=23;
cout<<"The operation must be bracketed, or you'll see..."<<endl;
cout<<"ia: "<<ia<<endl;
cout<<"ib: "<<ib<<endl;
cout<<"ic: "<<ic<<endl;
condition?ia=1, ib=2, ic=3:ia=21, ib=22, ic=23;
cout<<"The operation must be bracketed, or you'll see..."<<endl;
cout<<"ia: "<<ia<<endl;
cout<<"ib: "<<ib<<endl;
cout<<"ic: "<<ic<<endl;
return;
}
The output will be like:
Original:
ia: 0
ib: 0
After:
ia: 1
ib: 2
The operation must be bracketed, or you'll see...
ia: 21
ib: 2
ic: 23
The operation must be bracketed, or you'll see...
ia: 1
ib: 22
ic: 23
Is this legal?
This is a matter of operator precedence. Your expression:
condition?ia=1, ib=2, ic=3:ib=22,ia=21, ic=23;
is understood by the compiler as:
(condition?(ia=1, ib=2, ic=3):(ib=22)),ia=21, ic=23;
At this point you should be able to see why you get the program output.
Yes, the relevant grammar for a conditional expression is:
logical-or-expression ? expression : assignment-expression
for assignment expressions (which can also be a conditional-expression or a throw-expression):
logical-or-expression assignment-operator assignment-expression
and for an expression with a comma operator (an assignment-expression can also be an expression):
expression , assignment-expression
This means that the construct a ? b : c, d
cannot be parsed as equivalent to a ? b : (c, d)
because c, d
is not an assignment-expression but must be parsed as equivalent to (a ? b : c), d
.
There is no undefined behaviour in condition ? ia=1,ib=2,ic=3 : ia=21, ib=22, ic=23;
because evaluation of condition
is sequenced before the evaluation of either the second or third operands of ?:
and in every sub-expression containing a comma operator the evaluation of the first operand of the comma operator is sequenced before the evaluation of the second operand.
It's legal, but stupid not very useful to write code like that.
The code
condition?ia=1, ib=2, ic=3:ia=21, ib=22, ic=23;
is equivalent to
condition?(ia=1, ib=2, ic=3):ia=21;
ib=22;
ic=23;
just harder to read.
The problem is that the comma operator has the lowest precedence there is. Thanks to that, the else
part of the conditional operator is just the first assignment, after that the comma operator kicks in and the other two statements will be executed just aswell.
来源:https://stackoverflow.com/questions/9189522/something-we-found-when-using-comma-in-condition-ternary-operator