在某些情况下 - 特别是当异常在堆栈展开期间逃逸析构函数时 - C++ 运行时调用terminate()
它必须做一些合理的事后分析,然后退出程序。当出现“为什么如此严厉”的问题时,答案通常是“在这种错误情况下没有什么比这更合理的事情了”。如果整个程序都是用 C++ 编写的话,这听起来很合理。
现在,如果 C++ 代码在库中,而使用该库的程序不在 C++ 中怎么办?这种情况经常发生 - 例如,我可能有一个由 .NET 程序使用的本机 C++ COM 组件。一次terminate()
在组件代码内部调用.NET程序突然异常结束。程序作者首先会想“我不关心C++,为什么这个库会让我的程序退出?”
在 C++ 中开发库时如何处理后一种情况?是否合理terminate()
程序意外结束?有没有更好的方法来处理此类情况?
为什么 C++ 运行时调用terminate()
?它不是随机执行的,也不是由于编写代码时无法定义和/或避免的情况而执行的。它这样做是因为您的代码执行了一些定义为导致调用的操作terminate()
,例如在堆栈展开期间从析构函数抛出异常。
C++ 标准中有一个列表,列出了定义为导致调用的所有情况terminate()
。如果你不想terminate()
要被调用,请不要在代码中执行任何这些操作。这同样适用于unexpected()
, abort()
, 等等。
我认为这与您必须避免未定义的行为或通常避免编写错误的代码这一事实没有任何不同。您还必须避免已定义但不受欢迎的行为。
也许你有一个特定的例子,很难避免调用terminate()
,但在堆栈展开期间从析构函数抛出异常不是这样。只是永远不要从析构函数中抛出异常。这意味着设计您的析构函数,以便如果它们执行可能失败的操作,析构函数会捕获异常,并且您的代码将继续处于定义的状态。
在某些情况下,你的系统会因为你的 C++ 代码所做的事情而无礼地破坏你的进程(尽管不是通过调用terminate()
)。例如,如果系统过度使用内存并且 VMM 无法兑现承诺malloc/new
已经完成,那么你的进程可能会被杀死。但这是一个系统功能,可能同样适用于调用 C++ 的其他语言。我不认为您可以(或需要)对此做任何事情,只要您的调用者知道您的库可能会分配内存。在这种情况下,进程终止并不是代码的错误,而是操作系统对内存不足情况的定义响应。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)