2015-04-08 26 views
1

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

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

现在在清理类中的某些情况下,我在我的代码中使用了A中的析构函数;而反过来被称为B和B的则会抛出异常。

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

我最终改变了A的第三方代码来捕捉并忽略所有可能的异常。

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

+0

我无法解释您的问题。一个代码示例会有所帮助。无论如何,这是否会发生,有没有机会? “** 15.2/1 **当控制从抛出异常的地方传递到处理程序时,析构函数由本节中指定的进程调用,称为* stack unwinding *。如果直接由堆栈解绕调用的析构函数退出除了例外,调用了“std :: terminate”(15.5.1)。“ –

+0

MyCode清理A中定义的类。A调用B清理其内部成员。 B抛出异常。 M - > A(析构函数) - > B(例外)。这不是作为堆栈展开的一部分完成的。 B所拥有的资源是一个套接字连接,并且已经处于不良状态,这就是为什么我要清除套接字的用法,以便重新创建套接字连接。这是一个更大的系统的一部分,我不想崩溃,尤其是在我试图解决问题的操作上。 –

回答

0

我确实认为它是在标准的某个地方定义的,即从析构函数抛出的异常可能导致调用std::terminate,至少在C++ 11中是如此。这是因为编译器将析构函数隐式标记为noexcept

+0

种:http://stackoverflow.com/questions/15721544/destructors-and-noexcept/http://stackoverflow.com/questions/9180164/implicit-generated-members-and-noexcept和https:// akrzemi1。 wordpress.com/2013/08/20/noexcept-destructors/ –

+0

我喜欢这篇文章:https://akrzemi1.wordpress.com/2013/08/20/noexcept-destructors。谢谢。编译器的后续工作以及何时每个编译器中的行为发生变化将会很有帮助,因为此代码是跨平台的,并且可以在具有多个不同版本的同一编译器的许多不同机器上运行。 –