更新我的一些代码示例以进行培训我注意到之前由 CLR 保持未初始化的一些本地内存现在归零。
这是一个小的 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
我很好奇这次实施变更背后的理由。
所以任何反馈,特别是来自内部人士的反馈,或者对任何文章的参考,或者更好的反馈,都是受欢迎的。 :)
提前致谢。
答案 0 :(得分:2)
这只是一个巧合,没有任何故意清除你的当地人。抖动会尝试将本地保留在寄存器中,如果不需要,它甚至不会分配堆栈空间。你的程序很小,当你不用/ 32bitpreferred标志编译它时,它选择一个本地寄存器的好处很好,这个寄存器以前没有在当前线程上使用过,但仍然没有值。你可以在以下时收回垃圾:
我不确定为什么你需要在版本4.5中找到与以前版本相比未经初始化的值。也许这是抖动中某些变化的副作用,但我只是在猜测。关键是你仍然需要你的本地人的init标志,以确保他们得到零初始值。