Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

++ -- Operator precedence puzzle

Tags:

c#

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?

like image 621
Jurica Smircic Avatar asked Apr 30 '13 23:04

Jurica Smircic


People also ask

Which has more precedence * or?

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.

What are the precedence of operators?

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.

Which of the following operator has more precedence A () B ++ C * D >=?

Explanation: Operator ++ has the highest precedence than / , * and +.


2 Answers

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.

like image 118
Robert Harvey Avatar answered Sep 23 '22 12:09

Robert Harvey


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.

like image 29
Eric Lippert Avatar answered Sep 25 '22 12:09

Eric Lippert