I would like to start the translation with a small survey. A question for .NET developers who write in the C # programming language.
Poll at the end of the translation.Today I watched the internal list of C # language developers. One of the questions was about the behavior of the expression “x + = x ++”, namely, what should be the correct behavior. I think this question is more than interesting, so I decided to dedicate a blog entry to him. But for starters,
NEVER WRITE THIS CODE.')
OK, we can start ...
Use the following code as an example:
int x = 3; x += x++;
The first thing the compiler does when it sees the z + = y code is that it converts it to z = z + y. This is obviously true for the operators + =, - =, * =, / =.
OK, that was easy. Now, we can simply calculate the value of such an expression:
x = x + x++;
This code gives the same result as the code:
x = x + x;
However, it gives a different result with the code:
x = x++ + x;
which in turn gives the same result with the code:
x = x + ++x;
No matter how this behavior drives you crazy, it really has a place to be. But first, let's answer the question: what is the difference between x ++ and ++ x? x ++ returns the value of x to the current expression, and then increments it by one. ++ x increases the value of x by one and then returns the increased value to the current expression. Considering the above (and considering that C # processes left-to-right expressions), we can understand why the previous code works that way.
int x = 3; x = x + x++;
The compiler will calculate this expression as follows:
- x = (x) + x ++ -> the first x is calculated and returns the value 3, x = 3;
- x = 3 + (x) ++ -> x is calculated and returns 3, x = 3;
- x = 3 + (x ++) -> x ++ returns the value 3 and x is incremented by one, x = 4;
- x = (3 + 3) -> expression 3 + 3 is calculated and returns 6, x = 4;
- (x = 6) -> x is assigned the value 6 (rewriting the previous value 4).
Now let's see what will happen as a result of this code:
int x = 3; x = x++ + x;
- x = (x) ++ + x -> x is calculated and returns the value 3, x = 3;
- x = (x ++) + x -> x ++ returns the value 3 and x is incremented by one, x = 4;
- x = 3 + (x) -> x is calculated and returns the value 4, x = 4;
- x = 3 + 4 -> 3 + 4 expression is calculated and returns the value 7, x = 4;
- (x = 7) -> x is assigned the value 7 (rewriting the previous value 4).
Now consider the following code:
int x = 3; x = x + ++x;
- x = (x) + ++ x -> the first x is calculated and returns the value 3, x = 3;
- x = 3 + (++ x) -> ++ x increases x by one and returns 4, x = 4;
- x = 3 + (x) -> x is calculated and returns 4, x = 4;
- x = 3 + 4 -> 3 + 4 expression is calculated and returns 7, x = 4;
- (x = 7) -> x is assigned the value 7 (rewriting the previous value 4).
I hope everything is clear now. By the way, in C ++, the behavior of such an expression is undefined.
So why do we define the behavior of such an expression? Why don't we talk about the error, or why there is no warning at compile time?
- We were wrong, we should get an error or a warning, but now it's too late, because if we change this behavior, we can break the code; OR
- It is quite difficult to formulate a set of guidelines for the compiler so that it is able to tell about an error in such strange cases; OR
- We prefer to spend our time working on things that really care for people instead of smoothing out such sharp corners.
Does it matter which of the previous options is correct? Not really, because
YOU DON'T SHOULD WRITE THIS CODE !