3
#include <iostream>
using namespace std;

main(){

int i = 5;

cout << i++ << i--<< ++i << --i << i << endl;


}

The above program compiled with g++ gives output :

45555

While the following program:

int x=20,y=35;

x =y++ + y + x++ + y++;

cout << x<< endl << y;

gives result as

126

37

Can anyone please explain the output.

Mat
  • 202,337
  • 40
  • 393
  • 406
santhosh
  • 41
  • 1
  • 2

4 Answers4

13
cout << i++ << i--

is semantically equivalent to

operator<<(operator<<(cout, i++),   i--);
           <------arg1--------->, <-arg2->

$1.9/15- "When calling a function (whether or not the function is inline), every value computation and side effect associated with any argument expression, or with the postfix expression designating the called function, is sequenced before execution of every expression or statement in the body of the called function. [ Note: Value computations and side effects associated with different argument expressions are unsequenced. —end note ]

C++0x:

This means that the evaluation of the arguments arg1/arg2 are unsequenced (neither of them is sequenced before the other).

The same section in the draft Standard also states,

If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.

Now there is a sequence point at the semicolon at the end of the full expression below

operator<<(operator<<(cout, i++), i--);
                                      ^ the interesting sequence point is right here

As is clear, evaluation of both arg1 and arg2 lead to side effect on the scalar variable 'i', and as we saw above, the side effects are unsequenced.

Therefore the code has undefined behavior. So what does that mean?

Here is how 'undefined behavior' is defined :) in the Standard.

Permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message). Many erroneous program constructs do not engender undefined behavior; they are required to be diagnosed.

Do you see correlation with @DarkDust's response 'The compiler is even allowed to set your computer on fire :-)'

So any output you get from such a code is really in the dreaded realm of undefined behavior.

Don't do it.

Only thing that is defined about such code is that it helps OP and many of us get lots of votes (if answered correctly) :)

Paul R
  • 208,748
  • 37
  • 389
  • 560
Chubsdad
  • 24,777
  • 4
  • 73
  • 129
4

The result of the second program's expression is undefined. The compiler is even allowed to set your computer on fire :-) You're not allowed to modify a variable twice within one sequence point (in this case: from = to ;).

Edit:

For detailed explanations, see the C FAQ, specifically question 3.2.

DarkDust
  • 90,870
  • 19
  • 190
  • 224
  • *"You're not allowed to modify a variable twice within one sequence point"* You're saying that `x =y++ + y + x++ + y++;` is invalid in some way? – T.J. Crowder Oct 21 '10 at 10:22
  • 2
    T.J. Crowder> yes. even x = x++ is invalid. – nothrow Oct 21 '10 at 10:23
  • @Yossarian: Yeah, I just saw the `x++` (I thought he was talking about the `y++` stuff). Surprised it's invalid. *Useless*, but I'm surprised by "invalid." (BTW: If you put an `@` at the beginning of a reply to a comment giving the user's name, it'll notify them they have a comment. E.g., `@T.J. Crowder:` rather than `T.J. Crowder>`) – T.J. Crowder Oct 21 '10 at 10:25
  • @T.J.: Yes, it's invalid. For detailed explanations, see [the C FAQ](http://c-faq.com/~scs/cgi-bin/faqcat.cgi?sec=expr). – DarkDust Oct 21 '10 at 10:38
  • @T.J. Crowder: Even removing the `x++` that is still UB as there are two `y++` with no sequence points in between. – David Rodríguez - dribeas Oct 21 '10 at 10:39
  • @DarkDust and David: Thanks. I was never crazy enough to do it, had never run into that. :-) – T.J. Crowder Oct 21 '10 at 10:41
3

Adding to other's answers:

If you are using g++, using the -Wsequence-point option tells that:

$ g++ -Wsequence-point a.cpp
a.cpp: In function ‘int main()’:
a.cpp:8: warning: operation on ‘i’ may be undefined
                                          ^^^^^^^^^
codaddict
  • 445,704
  • 82
  • 492
  • 529
2

Undefined behaviour, so anything could happen

Chris Card
  • 3,216
  • 20
  • 15