【问题标题】:Variables more local than the rest of local variables ( is it really "more local" or just "isolated" from the rest that are "as local as" it's?)比其他局部变量更局部的变量(它真的是“更局部”还是只是与“与它一样局部”的其他变量“隔离”?)
【发布时间】:2015-12-17 17:31:08
【问题描述】:

我有一个非常小而直接的问题,我想得到一个确定的答案,并提前谢谢你们:

在方法内部(例如 main ),我可以为代码的任何部分添加花括号 {},以将某些行限定为局部变量。

这是我的例子:

public static void Main (string[] args)
{
int a = 1;

{ int b = 2;
Console.WriteLine(b); 
}

Console.WriteLine(a);


}

变量“int b”在花括号的外侧显然是不可访问的,现在我的问题是关于这个变量的内存位置,它是否会与 main 方法在同一个堆栈帧中内存堆栈,或者它将被保存在主方法堆栈顶部的新堆栈帧中(如被调用方法的参数和另一个方法中的局部变量)?

【问题讨论】:

  • 答案会因语言而异,用语言标记它有助于向可以提供帮助的人发出信号。这看起来像 C#,是吗?
  • 是的,没错,虽然我无法想象这将取决于 .NET 语言中的哪种语言
  • 使用 C# 或 .NET 对其进行标记,具有该专业知识的人将能够提供帮助。我自己是个JS人。 :)
  • 我会的。谢谢你,克里斯
  • 检查生成的 IL 代码。它们(也许很明显?)是等价的。 他们将留在哪里不像本地/班级成员那么简单。编译器将根据当前的实现决策及其类型决定

标签: c# memory-management scope local-variables stack-memory


【解决方案1】:

不,大括号不充当堆栈框架b 也是 main 方法的自动变量,将被视为与 a 相同,但具有额外的范围 因此,它将与 main 方法在同一个内存堆栈中的同一个堆栈帧中。

【讨论】:

  • 注意:编译器也可以决定将变量存储在 CPU 寄存器中,这样就不会占用堆栈上的任何空间。此外,编译器可以决定优化一个变量,然后它不会在任何地方占用任何存储空间。
  • @Ladi 感谢您的评论。它是抖动优化器执行的标准优化之一。你不需要或不能做任何事情。
【解决方案2】:

我认为区分lifetimescope会很有用:

由于局部变量的生命周期和范围之间的紧密联系,生命周期和范围经常被混淆。最简洁的说法是,至少只要当前“执行点”在局部变量的范围内,就可以保证局部变量的内容是活动的。 “至少一样长”当然意味着“或更长”;例如,捕获局部变量可以延长其生命周期

看看source

另外,根据此answer 并对其发表评论:

它在很大程度上是 JIT 编译器的实现细节。

C# 代码被翻译成 IL 代码和

IL 使用操作堆栈,但这并不直接对应于“调用堆栈”

看起来它依赖于实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-16
    相关资源
    最近更新 更多