Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preincrement vs postincrement in terms of sequence points

In this answer there're some examples of well-defined and undefined expressions. I'm particularly interested in two of them:

(6) i = i++ + 1;    // Undefined Behaviour
(7) i = ++i + 1;    // Well-defined Behaviour

This means that there's a difference between pre-increment and post-increment in terms of sequence points and well defined /unspecified/undefined behavior, but I don't understand where this difference comes from.

In standard draft (N4618) there's an example of code ([intro.execution], pt 18)

i = i++ + 1; // the value of i is incremented

i = i++ + i; // the behavior is undefined

Which, as far as I understand, means that expression i = i++ + 1 should be well-defined and the value of a variable i should increase by 1 as the result of this expression. However, this code run in MSVS 2015 increases i by 2.

So, what happens in the expression i = i++ + 1? Is it well-defined, undefined, implementation-defined or unspecified behavior? And is there any difference between pre-increment and post-increment in this and similar expressions in terms of sequence points and UB, as stated in the original answer? And why Visual Studio shows the behavior which is different from written in standard?

Please also note that I'm primarily interested in modern c++ (14/17).

like image 596
alexeykuzmin0 Avatar asked Dec 10 '25 04:12

alexeykuzmin0


1 Answers

What happens in the expression i = i++ + 1? Is it well-defined, undefined, implementation defined or unspecified behaviour?

This exact example is given in the standard, how lucky are we?

N4296 1.9.15 [intro.execution]

i = i++ + 1; // the behavior is undefined

Of course, we'd like to know why too. The following standard quote appears to be relevant here:

N4296 1.9.15 [intro.execution]

[ ... ] The value computations of the operands of an operator are sequenced before the value computation of the result of the operator. [ ... ]

This tells us that the sum will occur before the assignment (duh, how else does it know what to assign!), but it doesn't guarantee that the increment will occur before or after the assignment, now we're in murky water...

N4296 1.9.15 [intro.execution]

[ ... ] 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, and they are not potentially concurrent (1.10), the behavior is undefined. [ ... ]

The assignment operator has a side effect on the value of i, which means we have two side effects (the other is the assignment performed by i++) on the same scalar object, which are unsequenced, which is undefined.

Why does Visual Studio show the behavior which is different from written in standard?

It doesn't. The standard says it's undefined, which means it can do anything from what you wanted to something completely different, it just so happens that this is the behaviour that got spat out by the compiler!

like image 106
OMGtechy Avatar answered Dec 12 '25 19:12

OMGtechy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!