2
更新一些我的代码示例进行培训我已经注意到一些以前未被CLR未初始化的本地内存现在是归零。为什么在.Net 4.5中更改内存初始化规则?
这里是一个小CIL示例,演示了 “问题”:
.assembly Test{}
.assembly extern mscorlib{}
.class S extends [mscorlib]System.ValueType
{
.field public int32 n;
}
.method static void F()
{
.locals (int32, valuetype S)
ldloc 0
call void [mscorlib]System.Console::WriteLine(int32)
ldloca 1
ldfld int32 S::n
call void [mscorlib]System.Console::WriteLine(int32)
ret
}
.method static void Main()
{
.entrypoint
.locals (int32, valuetype S)
ldloc 0
call void [mscorlib]System.Console::WriteLine(int32)
ldloca 1
ldfld int32 S::n
call void [mscorlib]System.Console::WriteLine(int32)
call void F()
ret
}
这里是输出:
NET 2.0(我几乎可以肯定它与.Net 4.0相同):
$ /Windows/Microsoft.NET/Framework/v2.0.50727/ilasm.exe Test.il Microsoft (R) .NET Framework IL Assembler. Version 2.0.50727.5420 Copyright (c) Microsoft Corporation. All rights reserved. Assembling 'Test.il' to EXE --> 'Test.exe' Source file is ANSI Assembled global method F Assembled global method Main Creating PE file Emitting classes: Class 1: S Emitting fields and methods: Global Methods: 2; Class 1 Fields: 1; Resolving local member refs: 3 -> 3 defs, 0 refs, 0 unresolved Emitting events and properties: Global Class 1 Resolving local member refs: 0 -> 0 defs, 0 refs, 0 unresolved Writing PE file Operation completed successfully Test.il(6) : warning -- Non-sealed value class, made sealed $ ./Test.exe 211384 0 2157704 2157328
.net 4.5:
$ /Windows/Microsoft.NET/Framework/v4.0.30319/ilasm.exe Test.il Microsoft (R) .NET Framework IL Assembler. Version 4.0.30319.17929 Copyright (c) Microsoft Corporation. All rights reserved. Assembling 'Test.il' to EXE --> 'Test.exe' Source file is ANSI Assembled global method F Assembled global method Main Creating PE file Emitting classes: Class 1: S Emitting fields and methods: Global Methods: 2; Class 1 Fields: 1; Resolving local member refs: 3 -> 3 defs, 0 refs, 0 unresolved Emitting events and properties: Global Class 1 Resolving local member refs: 0 -> 0 defs, 0 refs, 0 unresolved Writing PE file Operation completed successfully Test.il(6) : warning : Non-sealed value class, made sealed $ ./Test.exe 0 0 0 0
我很好奇这背后实施变革的理由。
因此,欢迎任何反馈意见,尤其是来自内部人员,或对任何文章或更好的参考文献的参考。 :)
在此先感谢。
这几乎可以肯定地在CIL运行时规范中。你看过那里吗?将字段归零而不是未初始化字段几乎肯定比获取随机结果更可取。那里不需要太多理由。 –
在ECMA-335标准中,我看到“如果指定了init,变量将根据它们的类型初始化为其默认值:参考 类型被初始化为空,并且值类型被清零。但是这里没有“init”。 – Pragmateek
我怀疑Microsoft最初是否将变量初始化为语言编译器的决定。但是由于像你这样的人正在更频繁地挖掘真正的IL,并且IL程序和C#程序一样有效,所以将初始化重新推回到IL中是有意义的。 –