GCC(libstdc++)运行时如何决定在异常处于活动状态时终止()

How GCC (libstdc++) runtime decides to terminate() while an exception is active

我们知道如果异常当前处于活动状态并且有另一个对 throw.

的调用,则会调用 terminate()

想了解是什么导致这与 catch 块从 with-in 执行 throw 的情况不同?我假设一个 if a catch 块正在执行,它表示一个活动异常。

class exception_type{}

try{ ... throw obj; ... 
}catch(exception_type& obj){
 ...
 ... 
 throw x;
 ...
}

从这个代码示例中,因为我们在 catch 块中有另一个 throw,它应该被动态封闭的 try 块中的另一个处理程序捕获。 所以这似乎是 catchthrow 的有效使用。但此刻我们已经有一个异常活动。为什么它不应该导致 terminate() 被调用?或者换句话说,gcc 的 c++ 运行时如何准确地识别出已经存在异常活动并且需要调用 terminate()。

一旦异常被 catch 编辑(当控件进入 catch 部分时),它就会停止 'active'。

这个答案归功于@HolyBlackCat,他在他的回答中暗示了这一点。

throw 的响应是一个复杂的过程,其中 C++ 运行-time 需要执行多个不同的操作。虽然实际过程可能由 运行-time 的实现定义,但很少有东西可以共同理解。 This paper 可以提供更多信息。请参阅第 3.3 节。

在为 throw 提供服务的过程中,开始搜索合适的 catch。这本身可能会导致当前堆栈帧展开。展开堆栈框架的副作用是调用当前框架中对象的相应析构函数。这个调用析构函数的动作再次登陆用户代码区运行次(不安全)。完成后,我们再次进入运行时代的领地(更安全)。

最后,当输入合适的 catch 时,活动异常被销毁并开始执行处理程序的代码。因此,问题中显示的 throw 不会遇到任何活动异常。

这也解释了为什么我们不应该 throw 超出范围的析构函数异常。在析构函数中有一个 try{....}catch(...) 块实际上是一个很好的做法,以防止任何不幸的 terminate() 事件。