C++中goto语句对堆栈的影响

Mat*_*ias 4 c++ stack-overflow callstack goto destroy

goto在C++中执行语句时,下面的代码片段中的两个数组是否已从堆栈中删除?或者,当方法返回时,它们是否会从堆栈中删除?

retrySplit:
    ...
    uint32_t primsAbove[primitives.size()];
    uint32_t primsBelow[primitives.size()];
    ...
    goto retrySplit;
Run Code Online (Sandbox Code Playgroud)

此问题与使用goto语句导致的泄漏无关,但与是否可能炸毁堆栈有关.

Col*_*mbo 5

是的,阵列被破坏了.[stmt.jump]/2:

在从范围退出(但是已完成)时,在该范围内构造的具有自动存储持续时间(3.7.3)的对象将按其构造的相反顺序销毁.[...] 从一个循环中转出一个循环,或者从一个具有自动存储持续时间的初始化变量返回过去涉及销毁具有自动存储持续时间的对象,这些对象在转移点但不在转移点的范围内.

您还可以通过以下代码段验证这一点:

#include <iostream>

struct A
{
    A() {std::cout << "A";}
    ~A() {std::cout << "D";}
};

int main()
{
    int counter = 0;

    label:
        if (counter++) // Exit on second run. 
            return 0;

        A a;
        goto label;
}
Run Code Online (Sandbox Code Playgroud)

演示.你的输出应该是AD.请注意,counter跳回时不会被破坏label.


vz0*_*vz0 5

这个程序:

#include <iostream>

class X {
public:
 X() { std::cout << "ctor" << std::endl; }
 ~X() { std::cout << "dtor" << std::endl; }
};

int main(int argc, char** argv) {
 int i = 0;

label:
 X a;

 if (i == 0) {
  i = 1;
  goto label;
 }

 return 0;
}
Run Code Online (Sandbox Code Playgroud)

生成此输出:

$ ./a.out 
ctor
dtor
ctor
dtor
Run Code Online (Sandbox Code Playgroud)