How to translate “default(SomeType)” from C# to CIL?

可紊 提交于 2019-11-28 21:32:42

Can I conclude from all this that C#'s default(SomeType) corresponds most closely to CIL's initobj for non-primitive types and ldc.i4.0, ldnull, etc. for primitive types?

That's a reasonable summary but a better way to think about it is: if the C# compiler would classify default(T) as a compile time constant then the value of the constant is emitted. That is zero for numeric types, false for bool, and null for any reference type. If it would not be classified as a constant then we must (1) emit a temporary variable, (2) obtain the address of the temporary, (3) initobj that temporary variable via its address and (4) ensure that the temporary's value is on the stack when it is needed.

why does CreateClassNull<T> not just translate to ldnull, but to initobj instead?

Well, let's do it your way and see what happens:

... etc
.class private auto ansi beforefieldinit P
       extends [mscorlib]System.Object
{
  .method private hidebysig static !!T  M<class T>() cil managed
  {
    .maxstack  1
    ldnull
    ret
  } 
  ... etc

...

D:\>peverify foo.exe

Microsoft (R) .NET Framework PE Verifier.  Version  4.0.30319.17379
Copyright (c) Microsoft Corporation.  All rights reserved.

[IL]: Error: 
[d:\foo.exe : P::M[T]]
[offset 0x00000001]
[found Nullobjref 'NullReference']     
[expected (unboxed) 'T'] 
Unexpected type on the stack.
1 Error(s) Verifying d:\foo.exe

That would probably be why we don't do that.

Yes, that's what default does. You are correct in deducing it's just syntactic sugar for basically 0 (or equivalents).

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!