C Sharp

Increment Operators and Decrement Operators

As holdovers from the same shortcuts first introduced in the C language and carried forward in both C++ and Java, increment operators and decrement operators allow you to more concisely state that you want to increment or decrement a variable representing a numeric value by 1. Therefore, i++ is the equivalent of adding 1 to the current value of i.

Two versions of both the increment and decrement operators exist and often are a source of confusion. Typically referred to as prefix and postfix, the type of operator indicates when the side effect modifies the variable. With the prefix versions of the increment operator and decrement operator-that is, ++ a and -- a, respectively-the operation is performed and then the value is produced. With the postfix versions of the increment operator and decrement operator-a++ and a--, respectively-the value is produced and then the operation is performed. Take a look at the following example: -

using System;
class IncDecApp
{
    public static void Foo(int j)
    {
        Console.WriteLine("IncDecApp.Foo j = {0}", j);
    }
    public static void Main()
    {
        int i = 1;
        Console.WriteLine("Before call to Foo(i++) = {0}", i);
        Foo(i++);
        Console.WriteLine("After call to Foo(i++) = {0}", i);
        Console.WriteLine("\n");
        Console.WriteLine("Before call to Foo(++i) = {0}", i);
        Foo(++i);
        Console.WriteLine("After call to Foo(++i) = {0}", i);
    }
}

This application produces this result: -

Before call to Foo(i++) = 1
IncDecApp.Foo j = 1
After call to Foo(i++) = 2
Before call to Foo(++i) = 2
IncDecApp.Foo j = 3
After call to Foo(++i) = 3

The difference here is when the value is produced and the operand is modified. In the call to Foo(++i), the value i is passed (unchanged) to Foo and after the Foo method returns, i is incremented. You can see this in the following MSIL excerpt. Notice that the MSIL add opcode is not called until after the value has been placed on the stack.

IL_0013:  ldloc.0
IL_0014:  dup
IL_0015:  ldc.i4.1
IL_0016:  add
IL_0017:  stloc.0
IL_0018:  call       void IncDecApp::Foo(int32)

Now let's look at the preincrement operator used in the call to Foo(++a). In this case, the MSIL generated looks like the code shown here. Notice that the MSIL add opcode is called before the value is placed on the stack for the subsequent call to the Foo method.

IL_0049:  ldloc.0
IL_004a:  ldc.i4.1
IL_004b:  add
IL_004c:  dup
IL_004d:  stloc.0
IL_004e:  call       void IncDecApp::Foo(int32)