Behavior of Post Increment in Cout

Post-increment and Pre-increment concept?

All four answers so far are incorrect, in that they assert a specific order of events.

Believing that "urban legend" has led many a novice (and professional) astray, to wit, the endless stream of questions about Undefined Behavior in expressions.

So.

For the built-in C++ prefix operator,

++x

increments x and produces (as the expression's result) x as an lvalue, while

x++

increments x and produces (as the expression's result) the original value of x.

In particular, for x++ there is no no time ordering implied for the increment and production of original value of x. The compiler is free to emit machine code that produces the original value of x, e.g. it might be present in some register, and that delays the increment until the end of the expression (next sequence point).

Folks who incorrectly believe the increment must come first, and they are many, often conclude from that certain expressions must have well defined effect, when they actually have Undefined Behavior.

Pre increment and post increment

 result = y++ + z-- + x++;
3 1 2 = 6

if you perform this again

 result1 = y++ + z-- + x++;
4 0 3 = 7

reason

operator++ returns the original value, before incrementing the variable.

and

++operator returns the incremented value

-- is same as above just its decrement

Pre vs Post Increment

When exactly is that +1 getting added?

According to the standard:

The value computation of the ++ expression is sequenced before the modification of the operand object.

From a layman's point of view:

  1. Computation of counter is sequenced, which could be part of the entire RHS of the statement or just the term counter++.
  2. Computation of counter += 1 is sequenced before the next statement in the program is sequenced.

There are two things to keep in mind.

  1. The value of a term -- what it evaluates to in an expression.
  2. The side effects of the evaluation of the term.

In the case of counter++:

The value of the term is the value of counter before it is incremented.

The side effect of evaluation of the term is incrementing of the value of counter.

prefix operator behaviour in c++ when used multiple times in a statement

Earlier iterations of C++ (and C for that matter) had the concept of sequence points, where it was guaranteed all previous "things" (like the i++ side effect of evaluating that expression) would have completed.

This was replaced at some point with more tightly described "sequencing" along the lines of:

  • if A is sequenced before B, A will be fully done before B starts.
  • if A is sequenced after B, A will be not start until B is fully done.
  • if A and B are indeterminately sequenced, one will complete fully before the other starts, but you won't necessarily know which one went first.
  • if A and B are unsequenced, either may start first, and they may even overlap.

From C++20, [intro.execution], point 10 applies to your code:

Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.

That means that the individual bits of that full expression may happen in any order, and even overlap, resulting in differing results to what you may think is correct.

In other words, if you want deterministic code, don't do that.


And, despite your findings that the "postfix operator seems logical, it simply updates [the] value and uses it next time [the] variable is used, even when in same statement", that is actually incorrect.

While that may happen in a particular case, the expression (a++) * (a++) is equally as non-determinstic as (++a) * (++a).


If you want to guarantee the sequencing of your operations, you can use more explicit code like:

// int b = (++a) * (++a);
// with pre-increment immediately before EACH use of a:
int b = (a + 1) * (a + 2); a += 2;
// or:
int b = ++a; b = ++a * b

There are always ways to achieve the same effect with code that isn't subject to indeterminate results, in the same number of lines of code if you concern yourself with that sort of metric, albeit with two statements on a single line :-)

How the post-increment operator works exaclty. Are there some exceptions?

Isn't j=j++; equivalent to j = j; j++;

No absolutely not, and this is one of the most common misunderstandings about the pre and post increment operators.

The true equivalent of j = j++; is

int temp = j;
++j;
j = temp;

Beginners think that the post increment happens after everything else. But it's not true. The increment happens after the value is taken, not after the rest of the statement is executed. You can see that in the code above, the value of j is taken temp = j;, then the increment happens ++j;, then the value is used j = temp;.

And as has been said several times, this code only has a defined meaning from C++17, before that it was undefined.



Related Topics



Leave a reply



Submit