c++ - 为什么堆栈不回滚

标签 c++ operating-system stack

我们研究过 Stack 的扩展和收缩。但在实践中它不会发生 以一个从地址 100 扩展到 0 的堆栈为例,即第一个变量变为 100,然后是 99 等等。现在当我们编写以下代码时

int main()
{
   {
      int i;
      cout<<&i;//100 is displayed on screen
   }
   {
      int j;
      cout<<&j;//99 is displayed on screen
   }
}

现在当我们声明 i 时,它会转到地址 100,然后它的范围结束。然后 j 在新范围内声明,现在它应该再次具有地址 100,因为 i 已完成并且堆栈应该回滚但它没有,j 具有地址 99。为什么?你能解释一下吗??

最佳答案

标准没有对局部变量的存储做出这样的 promise 。没有理由相信声明的顺序与它们在内存中的排列顺序有任何关系。

这完全取决于编译器如何完成。实际上,对于您的程序,编译器可以为两个变量使用相同的地址。我希望任何体面的优化编译器都能这样做。

现在,在实践中,编译器很可能会使用您所说的各种优化。但是这些优化的实现方式因编译器而异。而且您描述的简单规则没有理由普遍适用于所有功能。编译器可以为一个函数选择一种策略,为不同的函数选择不同的策略。编译器的行为可能会有所不同,具体取决于其选项。

当然,如果你说的是函数调用相关的栈帧,那就不一样了。显然,当您进行新的函数调用时,会分配一个新的堆栈帧。然后当函数返回时,该栈帧被销毁,并重新进入调用函数的栈帧。但那是完全不同的事情,不是您在问题中讨论的内容。

关于c++ - 为什么堆栈不回滚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21365473/

相关文章:

c++ - 让 CMake 为 Visual Studio 中的单个源文件设置 "Exclude From Build"选项

c++ - 如何从其他目录树将源文件包含到 Bool.Test 用例中?

c++ - 将 RVO 对象传递给 std::vector::emplace_back

java - 为什么我的堆栈代码中的 pop 方法不执行?

assembly - 清理堆栈时可以将动态值(寄存器或内存)与 RET 一起使用吗?

java - resize() 方法被调用了多少次?

c++ - Windows高性能计数器的分辨率是多少?

c# - COSMOS - 操作系统开发 - 错误设置未启动?

operating-system - FIFO 页面替换如何工作?

c++ - 试图理解fork函数返回值的逻辑