转出一个块:析构函数被调用?

时间:2010-07-05 13:41:33

标签: c++ destructor goto

请考虑以下代码:

void foo()
{
    {
        CSomeClass bar;

        // Some code here...

        goto label;

        // and here...
    }

label:
    // and here...
}

是否会调用bar的析构函数?

4 个答案:

答案 0 :(得分:57)

C ++标准说:

  

退出范围时(但是   完成),析构函数(12.4)是   要求所有构造的对象   具有自动存储持续时间   (3.7.2)(命名对象或临时对象)   在该范围内声明的,在   他们的相反顺序   声明。

所以答案是肯定的。

答案 1 :(得分:24)

是的,他们会被召唤。

更新的 (这样做是可以的,getos并不比抛出虚拟异常或者使用bools / ifs更糟糕。函数中的简单goto不会使它成为意大利面条代码。)

答案 2 :(得分:8)

1)是的。 2)不要这样做。

详细说明:从概念上讲,这与通过break留下循环没有什么不同。但是,强烈建议goto强烈劝阻。几乎没有必要使用goto,应仔细检查任何用途,以了解发生了什么。

答案 3 :(得分:5)

是的,正如其他人所说的那样。 C ++指定/强制执行此操作。

但只是为了完整性而添加:如果您的goto使用在某些编译器中找到的计算 - goto扩展名 - gcc,clang,可能是其他人,但不是包括最后我知道的MSVC - 对象的析构函数是否会被调用是非常模糊的。当goto转到单个位置时,在控制流转移之前必须调用哪些析构函数非常清楚。但是使用计算的goto,可能需要动态调用不同的析构函数,以提供"期望的"语义。在这些情况下,我不确定实现此扩展的编译器是做什么的。我遇到这个问题的记忆就是当一个计算出来的goto可能会让一个带有非trival析构函数的对象的范围时,clang会发出警告,声称析构函数不会被调用。在某些情况下可能没问题,有些情况则没有。我不知道其他编译器会做什么。如果你想使用带有非平凡析构函数的对象计算goto s,请注意这个问题。