【问题标题】:C++ Exception handling blocked by destructorC++ 异常处理被析构函数阻塞
【发布时间】:2015-04-08 12:45:44
【问题描述】:

我最近在使用几个第三方库时遇到了问题。我的代码叫做库A,它调用了库B。当库B遇到错误时,它会抛出异常;这是首选行为,因为它不知道应该如何处理错误。库 A 将在其虚拟析构函数中使用 RAII 清理其内部资源。

由于这些资源是 A 中类的私有资源,因此我无法提前清理资源。

现在,在清理我在代码中使用的类的特定情况下,将调用 A 中的析构函数;依次调用 B 和 B 会抛出异常。

我想在我的代码中捕获这个异常,因为我不想更改第三方库的代码。不幸的是,我发现异常处理代码不会将异常传播回我的代码,但会导致调用中止方法。

我最终更改了 A 的第三方代码以捕获并忽略所有可能的异常。

由于默认情况下 gcc 4.8.1 不会通过析构函数传播异常,哪些主要编译器和这些编译器的版本会或不会通过析构函数传播异常?

【问题讨论】:

  • 我很难听懂你的解释。一个代码示例会有所帮助。无论如何,这种情况会发生吗? "15.2/1 当控制从引发异常的点传递到处理程序时,析构函数被本节中指定的进程调用,称为 stack unwinding。如果堆栈展开直接调用的析构函数退出异常,std::terminate 被调用 (15.5.1)。"
  • MyCode 清理 A 中定义的类。A 调用 B 清理其内部成员。 B 抛出异常。 M -> A(析构函数)-> B(异常)。这不是作为堆栈展开的一部分完成的。 B 拥有的资源是一个套接字连接,并且已经处于不良状态,这就是为什么我要清除对套接字的使用,以便我可以重新创建套接字连接。这是一个更大的系统的一部分,我不想崩溃,尤其是在我尝试从操作上解决问题时。

标签: c++ exception-handling destructor


【解决方案1】:

我确实相信标准中的某处定义了从析构函数抛出的异常会导致调用std::terminate,至少在 C++11 中是这样。这是因为析构函数被编译器隐式标记为noexcept

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2016-01-08
  • 2014-05-26
  • 1970-01-01
  • 2014-07-06
  • 2021-12-20
  • 2020-12-04
  • 1970-01-01
  • 2020-02-24
相关资源
最近更新 更多