我有一些代码,我从一个非常聪明的人那里继承了他们喜欢使用gotos离开try块,完全跳过catch块。
它绝对有效,我怀疑这是合法的(我认为C ++标准说在退出作用域时,所有内容都得到了适当的清理,我认为这适用于编译器必须做的任何事情来实现异常我的平台)。
这真的合法吗?这不是我写过的东西(它太聪明了一半),但它显然有效,我只是想明白为什么这样做。
答案 0 :(得分:9)
标准说是的,它是合法的&明确定义:
退出范围(无论多么完成),析构函数(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
。