局部变量作用域
本文关键字:作用域 局部变量 | 更新日期: 2023-09-27 18:08:36
我想要一些极客的建议,因为我不能再集思广益了。
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的局部变量?特别是' a '在if/else/goto块的作用域
在IL水平,
1)三个不重叠的局部变量"a"将作为一个临时存储槽生成并重用;我们知道这是安全的,因为它们没有重叠,它们都是相同的类型,并且它们具有相同的名称,因此调试器不会对它们感到困惑。或:
2)三个局部变量"a"将生成三个不同的临时存储槽,或
3)三个局部变量"a"将被确定为单赋值且无副作用的常量,并且在逻辑上被转换为常量,而不是变量。我认为我们目前没有进行这种优化,但我们保留将来这样做的权利。
在抖动级别,抖动可以自由地做任何它喜欢的事情。它可以生成一个堆栈槽。它可以分配一个寄存器。它可以生成多个堆栈槽,它可以分配多个寄存器。它可以把它们当作常数。抖动所能做的,只受限于抖动团队的聪明才智。
我不清楚你想要确定什么- c#语言在行为方面保证了什么,编译后的IL会是什么样子,或者jit编译的本机代码会是什么样子。
就IL而言,我希望在方法元数据中作为单独的局部变量结束。JIT可能会注意到它可以使用单个堆栈分配进行管理,并为所有三个变量重用它。然而,你既不应该知道也不应该关心这种情况是否会发生。三个a
变量在逻辑上是不同的,不会相互干扰。
(如果这不能回答你的问题,请明确你想确定什么…)
正如Eric Lippert所写:栈是一个实现细节。局部变量如何映射到堆栈取决于抖动实现。