C#ref struct参数内联

问题描述

我有一个有趣的问题。

假设我们具有以下功能:

int Add(int a,int b) => a + b;

int AddRef(ref int a,ref int b) => a + b;

如果这两个函数都内联,会有什么区别? (如果我理解正确的话,他们应该这样做)
裁判有什么改变吗?
毕竟,Add和AddRef都将内联到外部范围,并且已经在直接变量上进行操作

完整的示例场景:

[MethodImpl(MethodImplOptions.NoInlining)] // prevent Func1 from inlining
int Func1(int a,int b) => Add(a,b);

[MethodImpl(MethodImplOptions.NoInlining)] // prevent Func2 from inlining
int Func2(int a,int b) => AddRef(ref a,ref b);

编辑:

使用SharpLab进行了更多挖掘:

using System;
using System.Runtime.CompilerServices;

static class Main {
    
    public static int Foo(int a,b);
     
    public static int FooRef(int a,ref b);
    
    public static int FooNoInline(int a,int b) => AddNoInline(a,b);    
    
    public static int FooRefNoInline(int a,int b) => AddRefNoInline(ref a,ref b);
    
    static int Add(int a,int b) => a + b;
    
    static int AddRef(ref int a,ref int b) => a + b;
    
    [MethodImpl(MethodImplOptions.NoInlining)]
    static int AddNoInline(int a,int b) => a + b;

    [MethodImpl(MethodImplOptions.NoInlining)]
    static int AddRefNoInline(ref int a,ref int b) => a + b;
}

准时:

Main.Foo(Int32,Int32)
    L0000: lea eax,[rcx+rdx]
    L0003: ret

Main.FooRef(Int32,[rcx+rdx]
    L0003: ret

Main.FooNoInline(Int32,Int32)
    L0000: mov rax,Main.AddNoInline(Int32,Int32)
    L000a: jmp rax

Main.FooRefNoInline(Int32,Int32)
    L0000: sub rsp,0x28
    L0004: mov [rsp+0x30],ecx
    L0008: mov [rsp+0x38],edx
    L000c: lea rcx,[rsp+0x30]
    L0011: lea rdx,[rsp+0x38]
    L0016: call Main.AddRefNoInline(Int32 ByRef,Int32 ByRef)
    L001b: nop
    L001c: add rsp,0x28
    L0020: ret
   

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)