gpt4 book ai didi

c# - 堆栈 - 值类型的值存储在哪里?

转载 作者:行者123 更新时间:2023-11-30 14:01:46 30 4
gpt4 key购买 nike

void main()
{
int x = 5; // stack-allocated
Console.WriteLine(x);
}

我知道 x 是堆栈分配的。但是关于 x 的堆栈中实际上存储了什么?它保存的是“实际值”,还是包含该值的内存中某个位置的地址?

最佳答案

答案是响亮的“视情况而定”。

有一件事是肯定的:局部变量 x 的存储,如果它存在的话,包含一个实际值而不是一个引用,因为 int 是一个值类型。

在简洁的脑死亡翻译中,x 的实际值(不是指针或指向它的引用)存储在当前调用的激活记录中的局部变量中。生成的 IL 将是这样的:

  .maxstack 1
.locals init (int32 V_0)

ldc.i4.5 // push 5 on the evaluation stack
stloc.0 // pop it into x

ldloc.0 // now push a copy of x to pass to ...
call void [mscorlib]System.Console::WriteLine(int32)

ret // return

(请注意,.maxstack 指令谈论的是 IL 评估堆栈,不一定对应于 native 堆栈。如果评估堆栈较浅,则通常由 JIT 编译代码保存在寄存器中.)

在 CLR 的大多数当前实现中,激活记录及其局部变量将存储在 native 堆栈中。所以,我天真地认为 x 可以被认为是将其值存储在堆栈中。

在上述代码的优化编译(或优化 JIT 翻译)中,IL 中可能根本不存在局部变量存储。毕竟,为什么要分配局部变量存储来存储它,然后浪费两条指令来处理该局部变量,而您再也不需要它了?它可以作为 WriteLine 的常量参数内联:

  .maxstack 1
// Just pass 5 to WriteLine. No local variables here.
ldc.i4.5
call void [mscorlib]System.Console::WriteLine(int32)
// Bye.
ret

还有更多可能的并发症。如果函数在 C# 5 CTP 中被声明为 async,或者如果 x 被函数中其他地方的 lambda 表达式捕获,或者如果函数是使用yield return 语句,x 的存储最终可能会被强制放到堆上:它将成为编译器生成的类中的一个字段,这样变量的存储就可以在撕裂后继续存在- 如果闭包或延续超出局部作用域,则栈帧向下。

关于c# - 堆栈 - 值类型的值存储在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7684108/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com