Unexpected post-incremental assignment mode

Could you help me understand why the variable a does not increase in the first case, but it in the second case?

Case 1:

 int a = 10; a = a++; Console.WriteLine(a); //prints 10 

Case 2:

 int a = 10; int c = a++; Console.WriteLine(a); //prints 11 

I considered other similar issues, but could not find any features.

UPDATE 1: I think the program is flowing

Case 1:

 1. 'a' is assigned 10 2. 'a' is assigned 10 before increment happens 3. 'a' is incremented by 1 (Why doesn't this step affect the final value of 'a'?) 4. 'a' is printed --> 10 

Case 2:

 1. 'a' is assigned 10 2. 'c' is assigned 10 before 'a' is incremented 3. 'a' is incremented by 1 (Why does the increment of 'a' work here?) 4. 'a' is printed --> 11 

UPDATE 2:. Thanks to all the answers, I think I understood, please correct me if I am wrong.

Case 1:

 1. `a` is assigned 10 2. Compiler evaluates `a++`, stores old value 10 and new value 11 as well. Since it a post increment operation, assigns the old value to `a`. What i thought was, compiler would assign the old value 10 first and evaluate the `++` operation later. This is where i was wrong, compiler evaluates the RHS beforehand and assigns the value based on the operator. 4. 'a' is printed --> 10 

Case 2:

 1. `a` is assigned 10 2. Compiler evaluates `a++`, stores old value 10 and new value 11 as well. Since it a post increment operation, assigns the old value to `c` but value of `a` is preserved with `11`. 4. 'a' is printed --> 11 
+5
source share
7 answers

For me, the best way to understand some kind of behavior is to check the IL generated. In your first case, this is

 IL_0001: ldc.i4.s 0A // stack: 10 IL_0003: stloc.0 // a = 10, stack: empty IL_0004: ldloc.0 // stack: 10 IL_0005: dup // stack: 10, 10 IL_0006: ldc.i4.1 // stack: 10, 10, 1 IL_0007: add // stack: 10, 11 IL_0008: stloc.0 // a = 11, stack: 10 IL_0009: stloc.0 // a = 10, stack: empty IL_000A: ldloc.0 // stack: 10 IL_000B: call System.Console.WriteLine 

You can see that the stack still has the original value, and thus the created 11 will be overwritten at the end.

Let me try to explain it in simple words.

When you assign a value to a variable ( a = a++ ), the entire right-hand side of the assignment is first evaluated to guarantee the correct value as it is. So, nothing like 10 comes to you, the application continues and increases the value when the next line is executed.

Now imagine a post-increment as someone who first increases the value, but gives you your world so that you return the original value from the expression. And now you need to understand why 11 is overwritten. The increment goes first and, in the end, you get the original value of the promise (as IL shows).

+5
source

The first case a = a++ is a post-increment. Which says, adds 1 to a , but returns the previous value of a , and then saves the previous result back to a . It is mostly non-op.

If it was a preliminary increment, a = ++a , then a will be 11.

+6
source

There is nothing undefined here, as someone describes in a comment.

This is a well-defined behavior. To understand what is going on, you must first understand how the pre increment and post increment statements work.

Option 1:

a++ (post increment) will increment the value of a and store it in a , then return the value before it is incremented.

So, after executing a++; the value of a will be 11 , but the operator will return 10 .

Then a = a++; the destination part becomes a = 10; .

Case 2:

Sameway a++; increases the value of a to 11 and returns the previous value (10). to be assigned c . c will be 10, but a will be 11, because in this case you are not rewriting the value of a .

Your Case1 is equal to:

 int a = 10; int temp = a;//10 a = a + 1; //11 a = temp; //10 Console.WriteLine(a);//10 

and Case2 is equal to:

 int a = 10; int temp = a;//10 a = a + 1; //11 int c = temp;//10 Console.WriteLine(a);//11 

I hope you should now understand why you see what you see.

+3
source

This is not undefined behavior, and it is not a mistake. From the MSDN Documentation :

 The increment operator (++) increments its operand by 1. The increment operator can appear before or after its operand. The first form is a prefix increment operation. The result of the operation is the value of the operand after it has been incremented. The second form is a postfix increment operation. The result of the operation is the value of the operand before it has been incremented. 

Thus, MSDN reports that if you use this syntax (postfix):

 a = a++; 

Then the result of the operation will be assigned a a , and then increase. However, since the assignment operation has already taken place, you lose the result of the increment.

Using it (prefix):

 a = ++a; 

First, a will increase, then assign the incremental value of a .

EDIT

I will try to break it this way, I hope you understand better.

First of all, be aware that ++ always returns a value. If you are using a prefix version (e.g. ++a ), it returns the value a+1 . If you are using a postfix version (e.g. a++ ), it returns a before the increment occurs.

When executing this code:

 int a = 10; a = a++; 

You tell the compiler to assign a to a before incrementing. Therefore, a is 10 after that. An increment of 11 is lost at the bottom. Please note that you are not assigning 11 to a . You assign the old value before the increment, so you get pin 10 .

When executing this code:

 int a = 10; int b = a++; 

After completing the last line, it increments a equal to 11 and assigning 10 'b'. Since you are assigning another variable, a will not be overwritten with the original value of 10 , as in the first example.

To make it even more visual, see here:

 a = a++; ^ a is increased to 11, but the postfix increment returns the old value (10) 

This line effectively becomes:

 a = 10; int b = a++; ^ a is increased to 11, but b gets assigned a old value 

This line effectively becomes:

 int b = 10; a = a + 1; 

Does this make it clear?

+2
source

To be clear, there is something else between ++ a and a ++.

Both of them produce the same result, that is, to increase by 1, but the process is slightly different, and it can only be seen by assigning it to another variable.

This is the difference between pre and post increment you can look for

Case 1

  int a,b; a = 10; b = a++; //Here b is assigned by a post-incremented a, therefore b value is still 10 

Case 2

  int a,b; a = 10; b = ++a; //Here b is assigned by a pre-incremented a, b value is now 11 

Taken from http://en.wikipedia.org/wiki/Increment_and_decrement_operators

UPDATE

In response to this problem

 int a = 10; a = a++; 

the following process is performed:

1. the variable 'a' with an integer data type is created

2. the value of the variable "a" is assigned 10

3. Verify that the data is correct and correct. This means that the entire operation is performed on the right side (increment "a"). 'a' is now 11

4. Assign the value followed by the increment "a", which is 10, "a" is now 10

0
source

I do not think this behavior is undefined, as in the first case:

 int a = 10; a = a++; Console.WriteLine(a); //prints 10 

The value of a is the value before the increment action, which means that if we simplify a = a++ , then:

 a = a ; // `a` has `10` a++; // `a` has `11` 

and only then a has the value 11 .

Second case:

 int a = 10; int c = a++; Console.WriteLine(a); //prints 11 

Now c has a value of 10 , since the assignment operation does a value on the left side to get the value of the variable (on the right side) before the increment action, and only then the value on the right side rises by 1 .

0
source

You must print c in case 2. The result of the postmentment operator is always the value before the increment. Therefore, first give the value 10, then increase it to 11 and after that assign the operator result (10) to the left operand.

-1
source

Source: https://habr.com/ru/post/1211312/


All Articles