我想在这里有一些极客建议,因为我无法集思广益。
class sampleType
{
public void M1(bool someValue)
{
if (someValue)
{
int a = 1;
Console.WriteLine(a);
goto comehere;
}
else
{
int a = 2;
Console.WriteLine(a);
goto comehere;
}
comehere:
{
int a = 3;
Console.WriteLine(a);
}
}
}
假设: M1已经准备好执行了。 M1是线程堆栈中的最后一项(最后一个寄存器)。
问题:当前堆栈寄存器如何表示M1的局部变量?特别是在if / else / goto块中的'a'范围。
答案 0 :(得分:4)
在IL级,要么:
1)三个非重叠的局部变量“a”将作为单个临时存储槽生成并重新使用;我们知道这是安全的,因为它们不重叠,它们都是相同的类型,并且它们具有相同的名称,因此调试器不可能对它们感到困惑。或者:
2)三个局部变量“a”将生成为三个不同的临时存储槽,或
3)三个局部变量“a”将被确定为单赋值和无副作用的常量,并且逻辑上变为常数,而不是变量。我不相信我们此时会执行此优化,但我们保留将来的权利。
在抖动级别,抖动可随意做任何事情。它可以生成单个堆栈槽。它可以分配一个寄存器。它可以生成多个堆栈槽,可以分配多个寄存器。它可以将它们视为常量。抖动可以做的只受限于抖动团队的聪明才智。完全没有要求使用任何堆栈。
答案 1 :(得分:2)
我不清楚你要确定的是什么 - C#语言在行为方面保证什么,编译的IL会是什么样的,或者JIT编译的本机代码看起来像什么。
就IL而言,我希望期望这些最终成为方法元数据中的单独局部变量。可能的可能 JIT会注意到它可以使用单个堆栈分配进行管理,并将其重用于所有三个变量。但是,您既不知道也不关心是否会发生这种情况。三个a
变量在逻辑上是不同的,不会相互干扰。
(如果这不能回答您的问题,请澄清完全您要确定的内容......)
答案 2 :(得分:2)
Eric Lippert写道:The Stack Is An Implementation Detail。局部变量如何映射到堆栈取决于抖动实现。它没有用语言指定。