Compiled this source:
        unsafe static void _method1(int val)
        {
            int* x = &val;
            for (int i = 0; i < 10; i++)
            {
                x = x + 1; // increment x (add 4 to the pointer)
            }
        }
        unsafe static void _method2(int val)
        {
            int* x = &val;
            for (int i = 0; i < 10; i++)
            {
                x = (int*)(((byte*)x) + 1); // cast to a byte* and increment x (add 1 to the pointer)
            }
        }

Reflector decompiles it to this (both methods are exactly the same):
    private static unsafe void _method1(int val)
    {
        int* x = &val;
        for (int i = 0; i < 10; i++)
        {
            x++;
        }
    }

    private static unsafe void _method2(int val)
    {
        int* x = &val;
        for (int i = 0; i < 10; i++)
        {
            x++;
        }
    }


Here's the disassembly as IL
    .method private hidebysig static void _method1(int32 val) cil managed
    {
        .maxstack 2
        .locals init (
            [0] int32* x,
            [1] int32 i,
            [2] bool CS$4$0000)
        L_0000: nop 
        L_0001: ldarga.s val
        L_0003: conv.u 
        L_0004: stloc.0 
        L_0005: ldc.i4.0 
        L_0006: stloc.1 
        L_0007: br.s L_0014
        L_0009: nop 
        L_000a: ldloc.0 
>>>
        L_000b: ldc.i4.4 
>>>
        L_000c: conv.i 
        L_000d: add 
        L_000e: stloc.0 
        L_000f: nop 
        L_0010: ldloc.1 
        L_0011: ldc.i4.1 
        L_0012: add 
        L_0013: stloc.1 
        L_0014: ldloc.1 
        L_0015: ldc.i4.s 10
        L_0017: clt 
        L_0019: stloc.2 
        L_001a: ldloc.2 
        L_001b: brtrue.s L_0009
        L_001d: ret 
    }

    .method private hidebysig static void _method2(int32 val) cil managed
    {
        .maxstack 2
        .locals init (
            [0] int32* x,
            [1] int32 i,
            [2] bool CS$4$0000)
        L_0000: nop 
        L_0001: ldarga.s val
        L_0003: conv.u 
        L_0004: stloc.0 
        L_0005: ldc.i4.0 
        L_0006: stloc.1 
        L_0007: br.s L_0014
        L_0009: nop 
        L_000a: ldloc.0 
>>>
        L_000b: ldc.i4.1 
>>>
        L_000c: conv.i 
        L_000d: add 
        L_000e: stloc.0 
        L_000f: nop 
        L_0010: ldloc.1 
        L_0011: ldc.i4.1 
        L_0012: add 
        L_0013: stloc.1 
        L_0014: ldloc.1 
        L_0015: ldc.i4.s 10
        L_0017: clt 
        L_0019: stloc.2 
        L_001a: ldloc.2 
        L_001b: brtrue.s L_0009
        L_001d: ret 
    }

The subtle difference is the casting the pointer from (int*) to (byte*) before incrementing in _method2
z0rak
0

Comments

1 comment

  • Clive Tong
    I've logged that in our bug tracking system as RP-1075.
    Clive Tong
    0

Add comment

Please sign in to leave a comment.