gpt4 book ai didi

C++ 堆栈和作用域

转载 作者:可可西里 更新时间:2023-11-01 17:30:18 28 4
gpt4 key购买 nike

我在 Visual C++ 2008 上试过这段代码,它显示 A 和 B 没有相同的地址。

int main()
{
{
int A;
printf("%p\n", &A);
}

int B;
printf("%p\n", &B);
}

但是由于在定义 B 时 A 不再存在,所以在我看来可以重用相同的堆栈位置......

我不明白为什么编译器似乎没有做看起来非常简单的优化(例如,这在较大变量和递归函数的上下文中可能很重要)。而且似乎重用它不会增加 CPU 和内存的负担。有人对此有解释吗?

我猜答案是“因为它比看起来复杂得多”,但老实说我不知道​​。

编辑:关于以下答案和评论的一些精确度。

此代码的问题是每次调用此函数时,堆栈都会“增加一个整数”。当然,这在示例中没有问题,但考虑到大变量和递归调用,您会遇到可以轻松避免的堆栈溢出。

我建议的是内存优化,但我看不出它会如何损害性能。

顺便说一句,这发生在发布 版本中,所有优化都会开启。

最佳答案

像这样为本地人重用堆栈空间是一种非常常见的优化。事实上,在优化的构建中,如果您不获取局部变量的地址,编译器甚至可能不会分配堆栈空间,并且变量只会存在于寄存器中。

由于多种原因,您可能看不到这种优化。

首先,如果关闭优化(如调试构建),编译器将不会执行其中任何一项以使调试更容易 - 您可以查看 A 的值,即使它不再在函数中使用也是如此。

如果您正在使用优化进行编译,我的猜测是因为您正在获取本地地址并将其传递给另一个函数,编译器不想重用该存储,因为不清楚该函数正在做什么地址。

人们还可以想象一个编译器不会使用此优化,除非函数使用的堆栈空间超过某个阈值。我不知道有任何编译器会这样做,因为重用不再使用的局部变量空间的成本为零,并且可以全面应用。

如果堆栈增长是您的应用程序的一个严重问题,即在某些情况下您会遇到堆栈溢出,则不应依赖编译器对堆栈空间的优化。您应该考虑将堆栈上的大型缓冲区移动到堆中,并努力消除非常深的递归。例如,在 Windows 上,线程默认有 1 MB 的堆栈。如果您担心溢出,因为您在每个堆栈帧上分配 1k 内存并深入进行 1000 次递归调用,解决方法不是试图诱使编译器从每个堆栈帧中节省一些空间。

关于C++ 堆栈和作用域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1343190/

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