在某些情况下 - 特别是当一个异常在堆栈展开期间转义析构函数时 - C++运行时调用terminate()必须在事后做一些合理的事情然后退出程序.当出现"为什么如此苛刻"的问题时,答案通常是"在这种错误情况下没有更合理的事情".如果整个程序都是用C++编写的话,这听起来很合理.
现在如果C++代码在库中并且使用该库的程序不在C++中怎么办?这种情况经常发生 - 例如,我可能有.NET程序使用的本机C++ COM组件.一旦terminate()在组件代码中调用,.NET程序突然异常结束.程序作者首先会想到"我不关心C++,为什么这个库会让我的程序退出?"
在C++中开发库时,如何处理后一种情况?terminate()意外地结束该计划是否合理?有没有更好的方法来处理这种情况?
Ste*_*sop 11
为什么C++运行时调用terminate()?它不是随机执行,也不是由于编写代码时无法定义和/或避免的情况.这样做是因为你的代码执行了一些定义为导致调用的东西terminate(),例如在堆栈展开期间从析构函数中抛出异常.
C++标准中列出了所有情况的列表,这些列表被定义为导致调用terminate().如果您不想terminate()被调用,请不要在代码中执行任何操作.这同样适用于unexpected(),abort()等等.
我不认为这与你必须避免未定义的行为,或者通常避免编写错误的代码的事实有任何不同.您还必须避免已定义但不合需要的行为.
也许你有一个特殊的例子,很难避免调用terminate(),但是在堆栈展开期间从析构函数抛出异常不是这样.只是不要抛出析构函数中的异常.这意味着设计析构函数,以便在它们执行可能失败的操作时,析构函数捕获异常并且代码继续处于已定义的状态.
在某些情况下,由于您的C++代码所做的事情(尽管不是通过调用terminate()),您的系统会不礼貌地破坏您的过程.例如,如果系统过度使用内存并且VMM无法兑现malloc/new所做的承诺,那么您的进程可能会被终止.但这是一个系统功能,可能同样适用于调用C++的其他语言.我认为只要您的调用者知道您的库可能会分配内存,您就不能(或需要)做任何事情.在这种情况下,进程死亡并不是代码的错误,而是操作系统对低内存条件的定义响应.
我认为更基本的问题不是具体的终止,而是图书馆的设计.该库可能被设计为仅与C++一起使用,在这种情况下,可以在应用程序中适当地捕获和处理异常.
如果该库旨在与非C++应用程序一起使用,则需要提供一个接口,以确保没有异常离开库,例如执行catch(...)的接口.