走出try block是否合法?

时间:2012-07-12 19:03:36

标签: c++ standards

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

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

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

4 个答案:

答案 0 :(得分:9)

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

C ++ 2003:6.6跳转语句

  

退出范围(无论多么完成),析构函数(12.4)是   调用具有自动存储持续时间的所有构造对象   (3.7.2)(在此声明的命名对象或临时对象)   范围,与其声明的相反顺序。转出一个   循环,出一个块,或者返回一个初始化变量   自动存储持续时间涉及到变量的破坏   在转移点范围内的自动存储持续时间   来自但不是转移到。 (转入的是6.7   块)。 [注意:但是,程序可以终止(通过调用   exit()或abort()(18.3),例如),不破坏类对象   具有自动存储持续时间]

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

答案 1 :(得分:9)

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

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

if(0) {
unwind:
  longjmp(&lastSafePoint, 0);
}

我将它放入一个宏中,这样写起来非常方便。此处goto是清除在诊断异常的异常处理期间分配的资源所必需的。

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

答案 2 :(得分:6)

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

  

可以使用goto,break,return或continue语句进行传输   控制一个try块或处理程序。当发生这种情况时,每个   在try块中声明的变量将在上下文中被销毁   直接包含其声明。

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

但是请注意,使用goto(或switch)进入试用版是 确定

  

不应使用goto或switch语句将控制转移到try块或处理程序中。

答案 3 :(得分:3)

这是合法的。这是糟糕的代码。不要这样做。请勿使用goto