转出try块是否合法?

Mic*_*hne 3 c++ standards

我有一些代码,我从一个非常聪明的人那里继承,他们喜欢使用gotos离开try块,完全跳过catch块.

它确实有效,我怀疑这是合法的(我认为C++标准说在退出作用域时,所有内容都得到了适当的清理,我认为这适用于编译器必须做的任何事情来在我的平台上实现异常) .

这真的合法吗?这不是我写过的东西(太聪明了一半),但它显然有效,我只是想明白为什么这样做.

Joh*_*itb 10

它可以是合法的,它取决于代码的作用.例如,我编写了跳出catch块的代码,并且它在语言的运行时库中使用(为简单起见,使用运行时库的代码不实现itanium异常处理,但使用longjmp/setjmp实现).但是,运行时库通过C++异常确实使用它; 并且需要一种机制来干净地转移它们之间的控制.

try {
  doSomethingThatMayFail();
} catch(DiagnosticException&) {
  goto unwind;
}

if(0) {
unwind:
  longjmp(&lastSafePoint, 0);
}
Run Code Online (Sandbox Code Playgroud)

我把它放到一个宏中,这样写起来非常方便.在goto这里有必要诊断异常的异常处理期间分配清理资源.

一如既往,不要说"永远不要使用此功能".相反,必须仔细考虑每次使用.


Joh*_*ing 9

标准说是的,它是合法且定义明确的:

C++ 2003:6.6跳转语句

在从范围退出(但是已完成)时,将为所有具有自动存储持续时间(3.7.2)(命名对象或临时值)的构造对象调用析构函数(12.4),这些对象在其范围内声明,其声明的顺序与其声明的顺序相反.从循环中移出一个循环,或者从具有自动存储持续时间的初始化变量返回过去涉及销毁具有自动存储持续时间的变量,这些变量在转移点但不在转移点处的范围内.(转入块中见6.7).[注意:但是,程序可以终止(例如,通过调用exit()或abort()(18.3)),而不会破坏具有自动存储持续时间的类对象.]

我选择不首先评论使用的宗教含义goto.


Mic*_*urr 6

甚至比C++ 03标准关于跳转语句的部分更具体,它在"异常处理"子句(15/2)中说明了关于try-blocks的内容:

goto,break,return或continue语句可用于将控制转移到try块或处理程序之外.发生这种情况时,try块中声明的每个变量都将在直接包含其声明的上下文中被销毁.

C++ 11包含相同的措辞.

但请注意,使用(或)跳转到try-block 是不行的:gotoswitch

goto或switch语句不得用于将控制转移到try块或处理程序中.