几分钟前我遇到了“零成本”的异常处理,最后我去查了一下。我以前在例外情况和返回代码上下文中见过这个短语。以下是对“零成本”及其替代"setjmp/longjmp“的简短描述。
unw/Exception-Handling-Control.html
在运行时,GNAT使用两种方法处理异常。setjmp/longjmp方法在输入带有异常处理程序的框架时保存上下文。然后,当引发异常时,可以立即恢复上下文,而不需要跟踪堆栈帧。此方法提供了非常快速的异常传播,但为使用异常处理程序带来了很大的开销,即使没有异常引发。 另一种方法称为“零成本”异常处理。使用此方法,编译器将生成静态表来描述异常范围。当输入包含异常处理程序的框架时,不需要动态代码。当引发异常时,这些表用于控制子程序调用堆栈的回跟踪,以定位所需的异常处理程序。该方法对于异常的传播性能要差得多,但是如果不引发异常,则不存在异常处理程序的开销。
(GNAT是Ada编译器,但我猜上面的解释与语言无关。)
这有助于解释为什么我们首先要使用try --一些处理异常的策略需要在进入try块时保存上下文。
零成本策略听起来非常类似于goto风格的清理,当然我们不需要mightgoto块。try块对零成本策略有好处吗?对于使用此策略实现C++异常的编译器来说,如果语言允许裸throw Exception();语句,会有什么不同吗?try只是现代编译器的一种注释吗?
根据构建表的方式,零成本的成本可能取决于catch块的数量和位置,而不取决于try块的数量和位置。
肥皂盒:“零成本”这个名字是荒谬的误导。为什么不叫它“免费午餐”?
相关:
发布于 2015-03-04 14:49:05
try块是否对“零成本”堆栈展开策略是必要的,甚至是有帮助的?
是的,无论展开策略的细节如何,try块都是必要的。当抛出异常时,异常机制需要标识最近输入的try块,以便找到该块的关联处理程序。
使用“零成本”策略,为输入和离开块生成的代码将与常规块相同;它是一个try块这一事实只会影响用于堆栈展开的静态数据。
如果语言允许裸露的
throw Exception();语句,会有什么不同吗?
语言确实允许这样做。如果调用堆栈上有一个与某个try块相关联的适当处理程序,那么程序会跳到该处理程序;否则,它会调用terminate(),因为没有什么可以处理异常。
try块对零成本策略有好处吗?
这没什么意义。它们是识别要考虑的处理程序集合所必需的;从这个角度来看,它们首先允许它们工作,从而使所有解除策略“受益”。
try只是现代编译器的一种注释吗?
原则上,这可以在没有关键字标识块的情况下完成,也许可以将任何catch块与前面的语句关联起来。因此,人们可能认为它是公正的(相当有帮助的)文档。
https://stackoverflow.com/questions/28856241
复制相似问题