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

Ale*_* C. 43 c++ destructor goto

请考虑以下代码:

void foo()
{
    {
        CSomeClass bar;

        // Some code here...

        goto label;

        // and here...
    }

label:
    // and here...
}
Run Code Online (Sandbox Code Playgroud)

bar的析构函数会被调用吗?

小智 62

C++标准说:

在从范围退出(但是已完成)时,将为所有具有自动存储持续时间(3.7.2)(命名对象或临时值)的构造对象调用析构函数(12.4),这些对象在其范围内声明,其声明的顺序与其声明的顺序相反.

所以答案是肯定的.

  • 感谢您简洁地回答问题。整个“不要这样做”无助于理解您继承并试图理解的代码。 (2认同)

Vik*_*ehr 25

是的,他们会被召集.

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

  • +1否定自我中心的学生,因为他们个人认为必须是邪恶的,所以他们觉得需要投票.无论你的教授告诉你什么,Gotos都有有效的用途. (9认同)
  • @jwismar如果goto有助于代码可读性,我说继续使用它.合法使用的一个例子是逃避嵌套循环. (6认同)
  • "这样做是可以的,getos并不比抛出虚拟异常或者使用bools/ifs来解决问题更糟糕"抛出虚拟异常是一种可怕的方法(抛出异常通常非常昂贵)并且如果它介于两者之间和gotos,我肯定更喜欢gotos.但是,为这些案例编写函数肯定是最好的方法. (2认同)
  • @KevinK - Gotos 理论上可能有有效用途,但在实践中极为罕见。我认为,如果看起来您必须使用 goto,这种情况至少值得仔细检查。对于刚入门的开发人员,我建议避免使用它们是一个很好的学习方法。 (2认同)

jwi*_*mar 8

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

详细说明:从概念上讲,这与通过一个循环留下一个循环没有什么不同break. goto然而,强烈反对强烈劝阻.它几乎从来没有必要使用goto,应该仔细检查任何用途,以找出正在发生的事情.

  • 实际上,goto在很多情况下都很有意义. (15认同)
  • 休息更好.至少我知道我不会跳起来. (2认同)
  • 关于`goto`,`break`和`continue`的最坏情况是,一个区块末尾的"返回"并不意味着"控制无法超越这个".出于这个原因,我总是尽量避免这三个.我个人认为`break`和`goto`之间并没有多大区别.当然`goto`会有更多的恶化,但它并没有增加太多.所有这些都有其用途,但所有这些都使代码复杂化 (2认同)

Jef*_*den 5

是的,正如其他人所说。C ++对此进行指定/授权。

但这只是为了完整起见:如果您goto使用goto某些编译器(例如gcc,clang,可能还有其他编译器中找到的compute-extend),但我最后知道,包括MSVC,那么是否调用对象的析构函数就非常朦胧了。当a goto到达单个位置时,很清楚在控制流传输之前必须调用哪些析构函数。但是,通过计算后goto,可能需要动态调用不同的析构函数,以赋予“预期”语义。在这种情况下,我不确定实现此扩展的编译器会做什么。遇到这种情况,我的记忆是当计算出的goto可能会为带有非琐碎析构函数的对象留下范围,声称不会调用该析构函数。在某些情况下可能很好,而在其他情况下则不行。我不知道其他编译器会做什么。如果您要goto与非平凡析构函数的对象一起使用计算对象,只需注意这个问题。

  • 对于那些想知道计算 goto 是什么的人,请参阅 [此处](https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html) 或 [此处](https://stackoverflow.com/a /45380228/3075942)。 (3认同)