1

Every morning I get up grab my coffee and head on to SO to see what John Skeet has answered the day before. It's my daily reminder that how much I don't know. Today, for this question there was a discussion on the increment operators such as ++ and --. The MSDN doc says that ++ and -- have higher precedence than *. Consider this code:

         int c = 10;
         c = c++ * --c;

and this code

        int c = 10;
        c = (c++) * (--c);

in both cases c is 100. How would you force precedence (if possible at all) on this so the values in the parenthesis will be evaluated first before the multiplication?

Community
  • 1
  • 1
Zuzlx
  • 1,246
  • 14
  • 33
  • 3
    If what you want is `(c + 1) * (c - 1)` then you should write it as such (*clearly*) instead of playing with pre and post increment/decrement of the same variable in the same statement. – crashmstr Jan 08 '16 at 18:11
  • pre and post increment decrement update same variable with value, while c+1 or c-1 is different thing – Ehsan Sajjad Jan 08 '16 at 18:12
  • 1
    The question is not about style of the code. The question is about the outcome of an operation. – Zuzlx Jan 08 '16 at 18:13
  • It does. `c++` increment `c` so its value goes 11 and return 10 (postfix increment), then `--c` decrements `c` (11) so its value goes 10 and return it (infix decrement) ,then 10 *10 = 100 – Hamlet Hakobyan Jan 08 '16 at 18:13
  • 1
    Writing code like `c = c++;` is nonsensical. Just write `c = c + 2;` or `c++;` or whatever it is you actually mean. – Timothy Shields Jan 08 '16 at 18:14
  • @HamletHakobyan I think you hit the nail right on the head – Zuzlx Jan 08 '16 at 18:16
  • 2
    dont make things complex. its not a syntactic sugar. just google syntactic sugar and you get your answer. "_In computer science, syntactic sugar is syntax within a programming language that is designed to make things easier to read or to express_" `c++ * --c;` is not easy to read or to understand. because you are misusing `++` and `--` – M.kazem Akhgary Jan 08 '16 at 18:16
  • All you do is confusing yourself. Try using two different varaibles in the multiplication both initially set to 10 and observe. – CSharpie Jan 08 '16 at 18:17
  • @M.kazemAkhgary True but `++` and `--` are syntactic sugars. And that's what I was referring to. – Zuzlx Jan 08 '16 at 18:22
  • As a note `++` and `--` are prefix and postfix operators. – Matthew Whited Jan 08 '16 at 19:20

2 Answers2

3

The ++ after the variable will be applied only after the current instruction because it is a post increment. Use ++ or -- before a variabile to achieve what you want

int c = 10;
c = ++c * --c ;
Console.WriteLine ( c ) ;

This code will output 110 because 10 + 1 = 11 and 11 - 1 = 10 so 10 * 11 = 110

Skary
  • 1,322
  • 1
  • 13
  • 40
2

Computers work on a stack of operations.

The following...

int c = 10;
c = c++ * --c;

is compiled into these operations...

//OpCode      // Function                                             Stack      Var c
ldc.i4.s   10 // 10 is pushed onto the stack                          {10}
stloc.0       // pop the stack and store the value in location 0      {}         10
ldloc.0       // location 0 is pushed onto the stack                  {10}       10
dup           // stack value is copied and pushed on stack            {10,10}    10
ldc.i4.1      // 1 is added to the stack                              {10,10,1}  10
add           // top 2 values are popped and the sum is pushed        {10, 11}   10
stloc.0       // pop the stack and store the value in location 0      {10}       11
ldloc.0       // location 0 is pushed onto the stack                  {10}       11
ldc.i4.1      // 1 is added to the stack                              {10,11,1}  11
sub           // top 2 values are popped and the difference is pushed {10, 10}   11
dup           // stack value is copied and pushed on stack            {10,10,10} 11
stloc.0       // pop the stack and store the value in location 0      {10,10}    10
mul           // top 2 values are popped and the product is pushed    {100}      10
stloc.0       // pop the stack and store the value in location 0      {}         100
ldloc.0       // location 0 is pushed onto the stack                  {100}      100     

... I'm not sure that cleared anything up... but you can see while you were using the same variable everywhere (the stloc.0/ldloc.0) the actual operations work on the stack. (what I have in the braces {}). Operations (dup, add, sub, and mul) don't care about the variable indexes just the stack.

And for giggles...

int c = 10;
c = ++c * c--; 

... compiles into this...

//OpCode      // Function                                             Stack        Var c
ldc.i4.s   10 // 10 is pushed onto the stack                          {10}
stloc.0       // pop the stack and store the value in location 0      {}           10
ldloc.0       // location 0 is pushed onto the stack                  {10}         10
ldc.i4.1      // 1 is added to the stack                              {10,1}       10
add           // top 2 values are popped and the sum is pushed        {11}         10
dup           // stack value is copied and pushed on stack            {11,11}      10
stloc.0       // pop the stack and store the value in location 0      {11}         11
ldloc.0       // location 0 is pushed onto the stack                  {11,11}      11
dup           // stack value is copied and pushed on stack            {11,11,11}   11
ldc.i4.1      // 1 is added to the stack                              {11,11,11,1} 11
sub           // top 2 values are popped and the difference is pushed {11,11,10}   11
stloc.0       // pop the stack and store the value in location 0      {11,11}      10
mul           // top 2 values are popped and the product is pushed    {121}        10
stloc.0       // pop the stack and store the value in location 0      {}           121
ldloc.0       // location 0 is pushed onto the stack                  {121}        121
Matthew Whited
  • 22,160
  • 4
  • 52
  • 69