局部变量范围

时间:2011-09-15 13:48:53

标签: c#

我想在这里有一些极客建议,因为我无法集思广益。

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'范围。

3 个答案:

答案 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。局部变量如何映射到堆栈取决于抖动实现。它没有用语言指定。