1

could anyone please explain why when i write this code

    int x = 6;
    cout << x << endl << ++x << endl;

the output is 7 7

instead of

6 7

sorry i'm a beginner in this language , when i moved from VB.Net to C++ i feel it's more complicated ..

Mahmoud Sami
  • 55
  • 2
  • 9
  • 3
    My feeling is that, occasionally, these types of questions are worth answering. It's a more subtle variant of the ++i + i++ sort of thing. – Bathsheba Nov 09 '16 at 15:53
  • Since the dupe doesn't have a c++ tag you might also be interested in reading http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points – πάντα ῥεῖ Nov 09 '16 at 15:54
  • I don't really like that dupe since this one has overloaded operators. – Bathsheba Nov 09 '16 at 15:55
  • The dupe is inappropriate. It talks about undefined behaviour examples, but there is no undefined behaviour in this question - only implementation defined order of evaluation. Had it been `x << x++ < – Smeeheey Nov 09 '16 at 16:02
  • This isn't the problem, but don't use `std::endl` unless you need the extra stuff that it does. `'\n'` ends a line. – Pete Becker Nov 09 '16 at 16:22

2 Answers2

3
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.

Useless
  • 64,155
  • 6
  • 88
  • 132
2

In a c++ expression, evaluation order of sub-expressions is not specified by the standard and is left as implementation-defined. Thus in your expression your expectation that the x part is evaluated before the ++x part is unfounded: the standard makes no such requirement. In your case the ++x sub-expression is evaluated first, resulting in 7 being passed as the parameter value in both cases of the operator<< invocation. It could just as easily have been the other way round, leading to your expected output: both are correct from the standard's point of view.

Smeeheey
  • 9,906
  • 23
  • 39
  • C++ becomes a really great language - nobody knows what is correct and what is not. – Slava Nov 09 '16 at 16:18
  • Order of evaluation vs undefined behaviour is particularly notorious for this. I have seen questions again and again in which contradictory answers are given by really quite knowledgeable people – Smeeheey Nov 09 '16 at 16:23
  • If you required to be a language lawyer just to realize if expression is valid or not then language has bad problems. I am afraid language writers disconnect with reality more and more. :( – Slava Nov 09 '16 at 16:25
  • But you're not required to be a language lawyer to know that this example _just looks suspicious_. It takes some experience, but you don't need to recall the details to know it smells bad. – Useless Nov 09 '16 at 16:59