3

Possible Duplicate:
Undefined Behavior and Sequence Points

In C++ on a machine code level, when does the postincrement++ operator get executed?

The precedence table indicates that postfix++ operators are level 2: which means in

int x = 0 ; int y = x++ + x++ ; // ans: y=0 

The postfix ++'s execute first.

However, it would seem that the logical operation of this line is the addition happens first (0+0), but how does that happen?

What I imagine, is the following:

// Option 1: // Perform x++ 2 times. // Each time you do x++, you change the value of x.. // but you "return" the old value of x there? int y = 0 + x++ ; // x becomes 1, 0 is "returned" from x++ // do it for the second one.. int y = 0 + 0 ; // x becomes 2, 0 is "returned" from x++... but how? // if this is really what happens, the x was already 1 right now. 

So, the other option is although x++ is higher on the precedence table that x + x, the code generated due to x++ is inserted below the addition operation

// Option 2: turn this into int y = x + x ; // x++ ; x++ ; 

That second option seems to make more sense, but I'm interested in the order of operations here. Specifically, when does x change?

4
  • 1
    See stackoverflow.com/questions/4176328/…. This is undefined behavior (not just undefined order, anything is permitted to happen). Commented Mar 25, 2011 at 14:35
  • 4
    Operator precedence tells you nothing about order of evaluation. Commented Mar 25, 2011 at 14:41
  • The answer is the same, but the question is different. Commented Mar 25, 2011 at 16:20
  • I have voted to reopen. The question is not about the UB of the expression, but rather about the semantics of x++ Commented Mar 25, 2011 at 18:17

4 Answers 4

10

Instead of jumping on the details of the example that is UB, I will discuss the following example that is perfectly fine:

int a = 0, b = 0; int c = a++ + b++; 

Now, the precedence of operators means that the last line is equivalent to:

int c = (a++) + (b++); 

And not:

int c = (a++ + b)++; // compile time error, post increment an rvalue 

On the other hand, the semantics of the post increment are equivalent to two separate instructions (from here on is just a mental picture):

a++; // similar to: (__tmp = a, ++a, __tmp) // -- ignoring the added sequence points of , here 

That is, the original expression will be interpreted by the compiler as:

auto __tmp1 = a; // 1 auto __tmp2 = b; // 2 ++a; // 3 ++b; // 4 int c = __tmp1 + __tmp2; // 5 

But the compiler is allowed to reorder the 5 instructions as long as the following constraints are met (where x>y means x must be executed before y, or x precedes y):

1 > 3 // cannot increment a before getting the old value 2 > 4 // cannot increment b before getting the old value 1 > 5, 2 > 5 // the sum cannot happen before both temporaries are created 

There are no other constraints in the order of execution of the different instructions, so the following are all valid sequences:

1, 2, 3, 4, 5 1, 2, 5, 3, 4 1, 3, 2, 4, 5 ... 
Sign up to request clarification or add additional context in comments.

2 Comments

This is a very good answer and addresses the question directly. Ty.
In the example here and OP question you don't / can't get a real surprise though by those order variations. Mentioning examples with undefined / surprise results can tell the relevance of the explanation: e.g. int i = 0; i = (i++) + (i++); on gcc (v9) yields 1 in the end. Another compiler, MSVC, yields 2...
7

This

int y = x++ + x++ ; 

is undefined behavior. Anything can happen, including some unreasonable results, program crashing or whatever else. Just don't do that.

3 Comments

That code does't do what you make think it does, but ... program crashing ? I wouldn't say that.
@cprogrammer: The point is, it's undefined behavior. Crashing may not be likely, but it would be allowed.
@cprogrammer, @Fred Larson: The key idea here is that you should not waste time thinking of what might happen - stackoverflow.com/q/4265736/57428 - you should just not write code like that.
4

In C++ there are things called "sequence points". If you alter a value more than once without an intervening sequence point, the behaviour is undefined.

Consider the following:

int x = 0; int y = x++ + x++; 

The value of y could be 0, 1 or some other completely random value.

Bottom line is, don't do it. Nothing good can come of it. :-)

Comments

2

In your case, is seems like the following happens

When you use x++, x increments after the operation is complete.

int y = x++ + x++ ; // First add 0+0 // Increment x // Increment 

While

int y = ++x + ++x ; // Add (increment x) and (increment x) = 1+1 = 2 

However, different compilers will handle it differently and your application might crash if you increment twice in the same statement.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.