局部变量作用域

本文关键字:作用域 局部变量 | 更新日期: 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所写:栈是一个实现细节。局部变量如何映射到堆栈取决于抖动实现。