Question

What's happening here?

#include <iostream>
using namespace std;

int main(){

    int x=0,y=0;
    true? ++x, ++y : --x, --y; 
    cout << "x: " << x << endl;
    cout << "y: " << y << endl; //why does y=0 here?

    x=0,y=0;
    false ? ++x, ++y : --x, --y; 
    cout << "x: " << x << endl;
    cout << "y: " << y << endl;
}

x: 1
y: 0

x: -1
y: -1

The second case seems fine. I would expect both x and y to increment to 1 in the first case but only the left hand operand increments.

Was it helpful?

Solution

The first one is equivalent to:

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

The second one is equivalent to:

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

Thus the --y is always executed. In the first line, the increments are executed first so x = 1, y = 0 is expected. In the second line, the decrement of x is executed first so x = -1, y = -1 is expected.


As noted in a comment (to another answer) by Barmar:

And in case anyone is wondering why the comma between ++x and ++y doesn't have the same effect, it's because (true? ++x) would not be valid at all. So the compiler keeps scanning until it finds the :, but beyond that it stops when it reaches a lower precedence operator [(, in this example) or the end of statement].

OTHER TIPS

The y is zero because comma has the lowest precedence among all C++ operators. Because its precedence is lower than that of the ternary conditional operator, the conditional operators are parsed as true? ++x, ++y : --x and false? ++x, ++y : --x. In both cases, the --y statement is executed unconditionally.

EDIT The first comma is different because the compiler has found a ?, so now it needs a : to complete the "when true" expression of the conditional. That is why both ++x and ++y are taken in.

Read the standard

§5.18 Comma operator [expr.comma]

¶1 The comma operator groups left-to-right.

expression:
assignment-expression
expression , assignment-expression

A pair of expressions separated by a comma is evaluated left-to-right; the left expression is a discardedvalue expression (Clause 5).83 Every value computation and side effect associated with the left expression is sequenced before every value computation and side effect associated with the right expression. The type and value of the result are the type and value of the right operand; the result is of the same value category as its right operand, and is a bit-field if its right operand is a glvalue and a bit-field.

¶2 In contexts where comma is given a special meaning, [ Example: in lists of arguments to functions (5.2.2) and lists of initializers (8.5) —end example ] the comma operator as described in Clause 5 can appear only in parentheses. [ Example:

f(a, (t=3, t+2), c);

has three arguments, the second of which has the value 5. —end example ]

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top