Why does the ternary operator with commas evaluate only one expression in the true case?

As @Rakete said in their excellent answer, this is tricky. I’d like to add on to that a little.

The ternary operator must have the form:

logical-or-expression ? expression : assignment-expression

So we have the following mappings:

  • someValue : logical-or-expression
  • ++x, ++y : expression
  • ??? is assignment-expression --x, --y or only --x?

In fact it is only --x because an assignment expression cannot be parsed as two expressions separated by a comma (according to C++’s grammar rules), so --x, --y cannot be treated as an assignment expression.

Which results in the ternary (conditional) expression portion to look like this:

someValue?++x,++y:--x

It may help for readability’s sake to consider ++x,++y to be computed as-if parenthesized (++x,++y); anything contained between ? and : will be sequenced after the conditional. (I’ll parenthesize them for the rest of the post).

and evaluated in this order:

  1. someValue?
  2. (++x,++y) or --x (depending on boolresult of 1.)

This expression is then treated as the left sub-expression to a comma operator, with the right sub-expression being --y, like so:

(someValue?(++x,++y):--x), --y;

Which means the left side is a discarded-value expression, meaning that it is definitely evaluated, but then we evaluate the right side and return that.

So what happens when someValue is true?

  1. (someValue?(++x,++y):--x) executes and increments x and y to be 11 and 11
  2. The left expression is discarded (though the side effects of increment remain)
  3. We evaluate the right hand side of the comma operator: --y, which then decrements y back to 10

To “fix” the behavior, you can group --x, --y with parentheses to transform it into a primary expression which is a valid entry for an assignment-expression*:

someValue?++x,++y:(--x, --y);

*It’s a rather funny long chain that connects an assignment-expression back to a primary expression:

assignment-expression —(can consist of)–> conditional-expression –> logical-or-expression –> logical-and-expression –> inclusive-or-expression –> exclusive-or-expression –> and-expression –> equality-expression –> relational-expression –> shift-expression –> additive-expression –> multiplicative-expression –> pm-expression –> cast-expression –> unary-expression –> postfix-expression –> primary-expression

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)