cout << x << endl << ++x << endl;
translates to
cout.operator<<(x).operator<<(endl).operator<<(++x).operator<<(endl);
(where each operator<<
call returns a reference to cout for precisely this call chaining), and this is essentially the same as
operator<<(operator<<(operator<<(cout, x), endl), ++x)
(with the last/outermost call discarded for clarity, and the member function call rewritten as an equivalent free function).
Ignoring the endl
(which doesn't touch x
), the critical part is just a function call of the form
struct C;
C& f(C&, int);
...
f(f(c, x), ++x)
and, like any other function call, the order in which its arguments are evaluated is not defined. That is, the compiler can emit
int a = f(c, x);
int b = ++x;
f(a, b);
or
int b = ++x;
int a = f(c, x);
f(a, b);
There are good reasons for leaving this evaluation order unspecified (not undefined): different platforms have different calling conventions, and it gives the optimiser more room to manoeuvre.
Still, if you care about the order in which they're evaluated, you have to make it explicit.