Good point. I was conflating order of execution and order of evaluation.
But, your cout example is definitely counter-intuitive.
Code:
This:
cout << x << ' ' << x++ << endl;
is essentially this: (where op1, op2 stand for "operator")
op1<<( op2<<( op3<<( op4<<( cout, x), ' '), x++), endl);
where the op numbers are assigned like so:
cout << x << ' ' << x++ << endl;
4 3 2 1
The outermost view is
op1<<( op2<<(), endl). Order of evaluation doesn't matter in this case, since it only matters when the side-effects of evaluating one argument can effect the evaluation of the other.
In evaluating op2 the order _does_ matter.
op2<<( op3<<(), x++)If the arguments are evaluated right-to-left, op3 (and therefore op4) will use the incremented value and op2 will use the pre-incremented value. Hence your result. My compiler gives the more intuitive result (which is actually very misleading).
I can't understand this, however:
Code:
int x = 5, y = 100;
int z = x++ + x++ + y++;
printf( "%d\n", z);
Your compiler prints 110, and so does mine. But surely it should be 111, no matter what the order of evaluation? Associativity should yield:
op1+( op2+( x++, x++), y++)
(where op1 is the second + and op2 is the first + in the actual code).
Differences in the order of evaluation should pass arguments to op2 as either (5,6) or (6,5), and in either case op2 should yield 11 (+ 100 = 111).