1

Consider this piece of code

int j = 0;
int x = 0;

for(int i=0;i<5;i++){
    j = x++;
    cout<<x<<" ";
}

Output:

1 2 3 4 5

Now consider this

int j=0;

for(int i=0;i<5;i++){
    
    j = j++;
    cout<<j<<" "; 
}

Output:

0 0 0 0 0

My doubt is why is j not being incremented after it is assigned the value 0. Isn't j=j++; equivalent to j = j; j++; and if it isn't then what's going on with the first case. I know it's a silly doubt but I couldn't figure this out by myself.

user694733
  • 15,208
  • 2
  • 42
  • 68
  • 2
    `j++` evaluates to the previous value of `j`, zero on every occasion. By assigning it back to `j` you basically reset the latter. – bipll Aug 03 '20 at 09:40

5 Answers5

5

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.

john
  • 85,011
  • 4
  • 57
  • 81
2

My doubt is why is j not being incremented after it is assigned the value 0. Isn't j=j++; equivalent to j = j; j++; and if it isn't then what's going on with the first case.

No, because j = j++; is undefined. See this and other examples in https://en.wikipedia.org/wiki/Undefined_behavior#Examples_in_C_and_C++

artm
  • 17,291
  • 6
  • 38
  • 54
  • 4
    This is no longer undefined behavior in C++17: https://stackoverflow.com/questions/47702220/what-made-i-i-1-legal-in-c17 – VLL Aug 03 '20 at 09:50
  • @vll thanks, didn't know about that change in C++17 – artm Aug 03 '20 at 09:51
2
j = j++;
  • First, the right-hand side expression evaluates i.e j++.
  • As we know j++ returns the previous value of j (i.e value before incrementing j). So, here j++ returns 0.
  • Finally, this turns out to be j = 0;

The same thing happens every iteration and that's the reason only 0's are printed.

Note:

As others mentioned, this is defined behavior from C++17

Sai Sreenivas
  • 1,690
  • 1
  • 7
  • 16
1

It's a undefined behavior under c++11, and both clang++ and g++ complain about it.

test.cpp:7:10: warning: multiple unsequenced modifications to 'j' [-Wunsequenced]
    j = j++;
      ~  ^
1 warning generated.

But it's no longer ub in c++17.

Martins3
  • 67
  • 1
  • 8
0
j = j++;

lead to undefined behavior,there is a concept named sequence point in C++, see: https://en.wikipedia.org/wiki/Sequence_point

  • 1
    AFAIK, the concept of sequence points no longer exists in C++ since C++ 11. Instead, operations are defined as being sequenced before or after other operations. – Violet Giraffe Aug 03 '20 at 09:50
  • 3
    This is no longer undefined behavior in C++17: https://stackoverflow.com/questions/47702220/what-made-i-i-1-legal-in-c17 – VLL Aug 03 '20 at 09:50
  • @vll: Great point! You should post an answer. – Violet Giraffe Aug 03 '20 at 09:53