For the long time I thought I get it, and I was going to create some puzzles to learn some of my „students“ on the topic of operator precedence in c#. But it came out that I still don't get it right.
Puzzles: What’s the output here?
int a = 0;
int x = --a + a++;
Console.WriteLine(x);
Console.WriteLine(a);
Output:
-2 0
All clear here, I expected this
Next, the problem one:
int b = 0;
int y = b-- + b++;
Console.WriteLine(y);
Console.WriteLine(b);
Output:
-1 0
Well, here I also expected y to be -2… Now I’m trying to apply operator precedence rules and order of evaluation, and not sure I explained it to myself. Read this post again few times today, but still don’t quite get it why is the result here -1? Can someone help with how is the second result evaluated. why and how is it different than the first one?
Certain operators have higher precedence than others; for example, the multiplication operator has a higher precedence than the addition operator. For example, x = 7 + 3 * 2; here, x is assigned 13, not 20 because operator * has a higher precedence than +, so it first gets multiplied with 3*2 and then adds into 7.
The precedence of an operator specifies how "tightly" it binds two expressions together. For example, in the expression 1 + 5 * 3 , the answer is 16 and not 18 because the multiplication ("*") operator has a higher precedence than the addition ("+") operator. Parentheses may be used to force precedence, if necessary.
Explanation: Operator ++ has the highest precedence than / , * and +.
b--
is post-decrement. So:
b-- returns zero and subtracts 1 from b, leaving -1 in b.
b++ returns the -1 from the last step and adds 1, leaving 0 in b.
Final result of the addition: -1.
Do what the compiler does: break it down slowly and surely into equivalent programs.
int b = 0;
int y = b-- + b++;
is equivalent to
int b, y;
b = 0;
y = b-- + b++;
is equivalent to
int b, y;
b = 0;
int leftAddend = b--;
int rightAddend = b++;
y = leftAddend + rightAddend;
is equivalent to
int b, y;
b = 0;
int originalb1 = b;
int newb1 = originalb1 - 1;
b = newb1;
int leftAddend = originalb1;
int originalb2 = b;
int newb2 = originalb2 + 1;
b = newb2;
int rightAddend = newb2;
y = leftAddend + rightAddend;
And now annotate each with its value:
int b, y;
b = 0; // b is now 0
int originalb1 = b; // originalb1 is now 0
int newb1 = originalb1 - 1; // newb1 is now -1
b = newb1; // b is now -1
int leftAddend = originalb1; // leftAddend is now 0
int originalb2 = b; // originalb2 is now -1
int newb2 = originalb2 + 1; // newb2 is now 0
b = newb2; // b is now 0
int rightAddend = originalb2;// rightAddend is now -1
y = leftAddend + rightAddend;// y is now -1
This is precisely how the compiler deals with this situation; the compiler is just a bit more clever about optimizing away the temporaries. Analyzing expressions gets easy if you just break it down into simpler steps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With