gpt4 book ai didi

c# - 为什么 Int32.ToString() 发出调用指令而不是 callvirt?

转载 作者:太空狗 更新时间:2023-10-30 00:49:22 25 4
gpt4 key购买 nike

对于下面的代码片段:

struct Test
{
public override string ToString()
{
return "";
}
}

public class Program
{
public static void Main()
{
Test a = new Test();
a.ToString();
Int32 b = 5;
b.ToString();
}
}

编译器发出以下 IL:

  .locals init ([0] valuetype ConsoleApplication2.Test a,
[1] int32 b)
IL_0000: nop
IL_0001: ldloca.s a
IL_0003: initobj ConsoleApplication2.Test
IL_0009: ldloca.s a
IL_000b: constrained. ConsoleApplication2.Test
IL_0011: callvirt instance string [mscorlib]System.Object::ToString()
IL_0016: pop
IL_0017: ldc.i4.5
IL_0018: stloc.1
IL_0019: ldloca.s b
IL_001b: call instance string [mscorlib]System.Int32::ToString()
IL_0020: pop
IL_0021: ret

由于值类型 TestInt32 都覆盖了 ToString() 方法,我认为 a 中都不会发生装箱.ToString()b.ToString()。因此我想知道为什么编译器为 Test 发出 constraned+callvirt,为 Int32 发出 call >?

最佳答案

这是编译器对原始类型所做的优化。

但即使对于自定义结构,由于 constrained. 操作码,callvirt 实际上也会在运行时作为 call 执行 - 在这种情况下该方法被覆盖。它允许编译器在任何一种情况下发出相同的指令,并让运行时处理它。

来自 MSDN :

If thisType is a value type and thisType implements method then ptr is passed unmodified as the this pointer to a call method instruction, for the implementation of method by thisType.

和:

The constrained opcode allows IL compilers to make a call to a virtual function in a uniform way independent of whether ptr is a value type or a reference type. Although it is intended for the case where thisType is a generic type variable, the constrained prefix also works for nongeneric types and can reduce the complexity of generating virtual calls in languages that hide the distinction between value types and reference types.

我不知道关于优化的任何官方文档,但您可以在 Roslyn 存储库中看到关于 MayUseCallForStructMethod method 的备注.

至于为什么这种优化被推迟到非原始类型的运行时,我相信这是因为实现可以改变。想象一下,引用一个最初具有 ToString 覆盖的库,然后将 DLL(无需重新编译!)更改为删除覆盖的库。这会导致运行时异常。对于原语,他们可以确定这不会发生。

关于c# - 为什么 Int32.ToString() 发出调用指令而不是 callvirt?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38676162/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com