7

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?

Community
  • 1
  • 1
Jurica Smircic
  • 6,117
  • 2
  • 22
  • 27

5 Answers5

15

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.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
  • Thanks, this has to be right..looks like i got little rusty. Never came to my mind that b-- evaluates as 0 in the left operand but leaves -1 in b for the right operand. – Jurica Smircic Apr 30 '13 at 23:19
10

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.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • Thanks, makes sense, when dealing mostly with "high level" stuff these basic programming concepts tend to become "magic". And im always the one insisting on thinking about how things work behind the scene. Failed to do so here, but a good reminder. – Jurica Smircic May 01 '13 at 00:02
2
int b = 0;
int y = b-- + b++;

Break it down by step:

y = b--

Here, y is set to b (0), then b is decremented to -1.

+ b++

Here, y (0) is added to b (decremented to -1 in prev step) equaling -1, then b is incremented to zero. Output:

-1 0
Madbreaks
  • 19,094
  • 7
  • 58
  • 72
0

Postfix --/++ returns the original value of the variable. So:

With your example b-- + b++:

  • b-- means decrement b, return the original value. So b = b - 1, b is now -1, and the value of the expression is 0.
  • b++ means increment b, return the original value. So b = b + 1, b is now 0, and the value of the expression is -1.
  • Then, 0 + -1 == -1. This is y. b is still 0.
porges
  • 30,133
  • 4
  • 83
  • 114
0

This question has been answered, but I wanted to state the answer another way.

int b = 0;
int y = b-- + b++;

The expression b-- evaluates to 0 (the original value of b) and has the side effect (applied after evaluation) of decrementing b to -1.

The expression b++ evaluates to -1 (because of the previous side effect) and has the side effect (applied after evaluation) of incrementing b to 0.

This leaves the expression 0 + -1 which is -1.

Tergiver
  • 14,171
  • 3
  • 41
  • 68