2

Hey everyone, in the following code, what should the result of d be after the second expression?

        int d = 1;
        d += d++;

One would assume d is 3 afterwards but the unary increment d++ doesn't seem to take effect and d retains a value of 2.

Is there a name for this bug? Does it exist for other compilers that support unary increment like C#?

Sarah Vessels
  • 30,930
  • 33
  • 155
  • 222
t3rse
  • 10,024
  • 11
  • 57
  • 84
  • 19
    Asking why, or even if, the compiler is wrong is quite often the wrong question. Asking why your particular happens is probably the correct question. Today's C# compiler has been put through just a *small* amount of rigorous testing and usually deserves the benefit of the doubt. – Dinah Oct 12 '09 at 18:59
  • Not sure if that's a bug, I would have thought the answer to be 3 as well, but d's value if evaluated at the postfix ++ is 1 one, so the answer is 2 then, or is the operator evaluated at the ? – kenny Oct 12 '09 at 18:59
  • it is not a bug, it is a feature :) – idursun Oct 12 '09 at 19:00
  • @Dinah, I think David gives proper doubt with his '...Bug?' – kenny Oct 12 '09 at 19:01
  • Don't rush to claim that you have found a bug: http://catb.org/~esr/faqs/smart-questions.html#id382249 – Sinan Ünür Oct 12 '09 at 19:02
  • 5
    @Kenny Nah, a mere '?' cannot make up for the fact that *David in Dakota* thought there was at least a 50% chance that this might be computer bug rather than his lack of understanding. – Sinan Ünür Oct 12 '09 at 19:07
  • 1
    d = (2*d)+1 is much less confusing even if a bug doesn't exist. – Greg Oct 12 '09 at 19:12
  • Sorry for the wording of my question, I've restated to try to clarify I just wanted an explanation of what was going on. – t3rse Oct 12 '09 at 19:13
  • the pre and post increment/decrement operators have wonderful and interesting behavior. – QueueHammer Oct 12 '09 at 19:20
  • 2
    There is a bug in any developer that would write such code. – Cheeso Oct 12 '09 at 19:59

9 Answers9

33

It's not a bug, it acts exactly as expected.

The += operator expands into this:

d = d + d++;

That means that the change that the ++ operator causes is overwritten when the result is assigned back to the variable.

JohnFx
  • 34,542
  • 18
  • 104
  • 162
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
16

If you take a look at the generated IL, you'll see why the result is 2 and not 3.

IL_0000:  ldc.i4.1  // load constant 1 on evaluation stack
IL_0001:  stloc.0   // pop and store value in local 0
IL_0002:  ldloc.0   // load value of local 0 on evaluation stack
IL_0003:  ldloc.0   // repeat, stack is now 1, 1
IL_0004:  dup       // duplicate topmost value on evaluation stack, 
                    // i.e. stack is now 1, 1, 1
IL_0005:  ldc.i4.1  // load constant 1 on evaluation stack
IL_0006:  add       // add two topmost values on stack, 
                    // i.e. 1 and 1 and push result on stack
IL_0007:  stloc.0   // pop and store this value in local 0
IL_0008:  add       // add the two remaining values on the stack
                    // which again happens to be 1 and 1 and push result to stack
IL_0009:  stloc.0   // pop and store this value in local 0

In other words: The final value stored is the sum of 1 and 1.

(the code above is from release mode build)

Brian Rasmussen
  • 114,645
  • 34
  • 221
  • 317
12

If you rewrite your code this way, it will set d to have a value of 3:

int d = 1;
d += ++d;

Take a look at the ++ Operator documentation for an explanation as to why your example behaves the way it does.
Excerpt:

The second form is a postfix increment operation. The result of the operation is the value of the operand before it has been incremented.

As @Guffa pointed out, it's not a bug, it's simply that the result of your postfix increment operation in d is being overwritten by the += operation.

JeffH
  • 10,254
  • 2
  • 27
  • 48
Donut
  • 110,061
  • 20
  • 134
  • 146
4

I frequently get questions about the ++ operators being "broken"; almost always it is because the person asking the question is used to the way it works in some language where behaviour ++ is not well-defined, like C++. Here's a recent article I wrote about such a scenario:

http://blogs.msdn.com/ericlippert/archive/2009/08/10/precedence-vs-order-redux.aspx

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
2

Have you tried ++d? Isn't d++ evaluated after?

wsorenson
  • 5,701
  • 6
  • 32
  • 29
  • Be careful. Evaluated after *what*, exactly? The chief difference between ++d and d++ is that the evaluation of the result of the expression happens either before or after the *storage* of the incremented result into the variable. It is a common error to believe that the evaluation of the postfix expression *as a whole* somehow happens "later" than other parts of the expression in which it is embedded, but this is a myth. – Eric Lippert Oct 12 '09 at 19:36
  • Right. If the ++ was applied after the entire expression was evaluated, then we would expect to see 3. – wsorenson Oct 12 '09 at 21:01
2

I think behavior of d++ is different than ++d, though the final result stored in d is the same.

elitalon
  • 9,191
  • 10
  • 50
  • 86
LJM
  • 6,284
  • 7
  • 28
  • 30
1

Silly code is unpredictable. Might I recommend

d += 2;
Amy B
  • 108,202
  • 21
  • 135
  • 185
  • 3
    It's not unpredictable at all. The language specification is very clear about what this code should do. I agree it's silly though. – Jon Skeet Oct 12 '09 at 18:59
  • 1
    not "unpredictable", but definitely "needlessly hard to predict", which I think is close enough. :) – jalf Oct 12 '09 at 20:17
1

d++ and ++d are different. Also known as "Select Isn't Broken."

JesperE
  • 63,317
  • 21
  • 138
  • 197
1

...and this would be an example of the reason why I find the post/pre- increment/decrement operators to be highly unreadable when used in an expression with other operators. The behavior you describe is correct, but hard to reason about, leading to misunderstandings and bugs.

Even though it's wordier I would rewrite this as:

int d = 1;
d += d;
++d;

Note the use of the pre-increment operator instead of the post-increment so that the compiler doesn't think it needs to keep a copy of the old value.

tvanfosson
  • 524,688
  • 99
  • 697
  • 795