Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference in IL for ref paramters

Tags:

c#

ref

cil

I am trying to understand the difference between the way parameters passed by reference and value are treated at IL level.

Here are the two methods in C#

    public static void TestRef(ref int x)
    {
        x++;
    }
    public static void Test(int x)
    {
        x++;
    }

The IL for pass by value is below, I understand that it loads the arg, then the int constant 1 and adds it and stuffs it back on the stack.

  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  ldc.i4.1
  IL_0003:  add
  IL_0004:  starg.s    x
  IL_0006:  ret

The IL for the method which passes by reference:

IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  ldarg.0
  IL_0003:  ldind.i4
  IL_0004:  ldc.i4.1
  IL_0005:  add
  IL_0006:  stind.i4
  IL_0007:  ret

I don't understand why the two ldarg.0 statements are there. I assume the IL_0002/3 are just loading the argument address and then the argument value for that address.

But then what about IL_0001? Is it something to do with the left hand side of x =x+1?

like image 616
peeyush singh Avatar asked Apr 01 '26 16:04

peeyush singh


1 Answers

The address loaded at IL_0001: ldarg.0 will be consumed by the storing operation at IL_0006: stind.i4.

The msdn tells us about the stind.i4 opcode:

The stack transitional behavior, in sequential order, is:

  1. An address is pushed onto the stack.

  2. A value is pushed onto the stack.

  3. The value and the address are popped from the stack; the value is stored at the address.

https://learn.microsoft.com/de-de/dotnet/api/system.reflection.emit.opcodes.stind_i4?view=netframework-4.8

like image 74
thehennyy Avatar answered Apr 04 '26 07:04

thehennyy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!