C++ 当异常处于活动状态时,GCC(libstdc+;+;)运行时如何决定终止()
我们知道,如果异常当前处于活动状态,并且有另一个调用C++ 当异常处于活动状态时,GCC(libstdc+;+;)运行时如何决定终止(),c++,exception,gcc,g++,C++,Exception,Gcc,G++,我们知道,如果异常当前处于活动状态,并且有另一个调用throw,则调用terminate() 想了解是什么原因导致这与catch块从中抛出时的情况有所区别吗?我假设如果执行catch块,则表示活动异常 class exception_type{} try{ ... throw obj; ... }catch(exception_type& obj){ ... ... throw x; ... } 从这个代码示例中,因为在catch块中有另一个throw,它应该被动态封闭的
throw
,则调用terminate
()
想了解是什么原因导致这与catch
块从中抛出时的情况有所区别吗?我假设如果执行catch
块,则表示活动异常
class exception_type{}
try{ ... throw obj; ...
}catch(exception_type& obj){
...
...
throw x;
...
}
从这个代码示例中,因为在catch
块中有另一个throw
,它应该被动态封闭的try
块中的另一个处理程序捕获。
所以这似乎是在catch
中有效地使用throw
。但目前我们已经有一个异常活动。为什么它不应该导致调用terminate
()?或者换句话说,GCC的C++运行时如何识别已经存在异常,而“<代码>终止< /COD>())需要调用。< /P> < P>异常一旦“<代码> catch /<代码> ED(当控件进入<代码> catch <代码> >节)时,将停止为“活动”。.这个答案归功于@HolyBlackCat,他在回答中暗示了这一点
< > <代码>投掷是一个复杂的过程,其中C++运行时需要执行几个不同的动作。虽然实际的过程可能是由运行时的实现定义的,但是很少有共同点可以理解。可能会有更多的光。请参见第3.3节
在维护抛出
的过程中,会启动对适当的捕获
的搜索。这本身可能会导致当前堆栈帧的展开。展开堆栈帧的副作用是调用当前帧中对象的相应析构函数。再次调用析构函数的操作会将运行时降落到用户的代码区域(不安全)。完成后,我们再次进入运行时的区域(更安全)
最后,当输入一个合适的catch
时,活动异常被销毁,并开始执行处理程序的代码。因此,如所示的抛出
,不会遇到任何活动异常
class exception_type{}
try{ ... throw obj; ...
}catch(exception_type& obj){
...
...
throw x;
...
}
这也解释了为什么我们不应该从超出范围的析构函数中抛出异常。实际上,在析构函数中使用try{…}catch(…)
块是一种很好的做法,可以防止任何意外的终止
()事件。我说的是catch块中的抛出。它不必是最初抛出的同一个异常对象。@VTT谢谢,我这次尝试了示例。谢谢+1,我现在可以回忆起“IA-64的C++异常处理”一文中的细节。您介意我在自己对问题的回答中详细解释一下吗。@最终原因当然,我不介意。这毕竟是你的问题。