这三个之间有什么区别?在无法正确处理的异常情况下,我应该如何结束程序?
std::abort
如果无法在析构函数中解决异常,则是合理的。
std::terminate
请参阅安杰出色的这些C ++篇博客:akrzemi1.wordpress.com/2011/09/28/who-calls-stdterminate,akrzemi1.wordpress.com/2011/10/05/using-stdterminate
这三个之间有什么区别?在无法正确处理的异常情况下,我应该如何结束程序?
std::abort
如果无法在析构函数中解决异常,则是合理的。
std::terminate
请参阅安杰出色的这些C ++篇博客:akrzemi1.wordpress.com/2011/09/28/who-calls-stdterminate,akrzemi1.wordpress.com/2011/10/05/using-stdterminate
Answers:
我的建议是不要使用其中任何一个。相反,catch
您无法在其中处理main()
并return
仅从那里处理的异常。这意味着您可以确保正确展开堆栈并调用所有析构函数。换一种说法:
int main() {
try {
// your stuff
}
catch( ... ) {
return 1; // or whatever
}
}
abort表明程序“异常”结束,并引发POSIX信号SIGABRT,这意味着将调用您为此信号注册的任何处理程序,尽管在两种情况下程序仍将终止后缀。通常,您会abort
在C程序中使用它来退出意外错误情况,在这种情况下错误很可能是程序中的错误,而不是诸如输入错误或网络故障之类的错误。例如,abort
如果逻辑上永远不应该在数据结构中发现NULL指针,则可能会发生这种情况。
退出表示程序“正常”结束,尽管这仍可能表示失败(但不是错误)。换句话说,exit
如果用户提供了无法解析的输入或无法读取的文件,则可能带有错误代码。退出代码0表示成功。exit
还可以选择在结束程序之前调用处理程序。这些已在atexit
和on_exit
功能中注册。
std :: terminate是在存在未处理的异常时在C ++程序中自动调用的内容。从本质abort
上讲,它等效于C ++ ,假设您要通过抛出异常来报告所有异常错误。这将调用由函数设置的处理程序,该std::set_terminate
函数默认情况下仅调用abort
。
在C ++中,通常最好避免调用abort
或exit
出错,因为最好抛出异常,让代码进一步进入调用堆栈,以决定是否结束程序是合适的。是否使用exit
成功取决于具体情况-在s中的return语句以外的其他地方结束程序是否有意义main
。
std::terminate
即使在C ++中,也应被视为最后的错误报告工具。问题std::terminate
在于终止处理程序无权访问未处理的异常,因此无法知道它是什么。通常,将整个main打包在一个try { } catch (std::exception& ex) { }
块中通常要好得多。至少然后您可以报告有关派生自的异常的更多信息std::exception
(当然,不是派生自的异常std::exception
最终仍将无法处理)。
包装main
in 的主体try { } catch(...) { }
并不比设置终止处理程序好多少,因为您同样无法访问有问题的异常。编辑:根据尼尔·巴特沃思(Neil Butterworth)的回答,这样做的好处是,在这种情况下,堆栈是未缠绕的,对于未处理的异常,这是不正确的(有点令人惊讶)。
std::current_exception()
。在此处查看示例:akrzemi1.wordpress.com/2011/10/05/using-stdterminate
std :: abort和std :: exit(还有更多:std :: _ Exit,std :: quick_exit)只是较低级别的函数。您可以使用它们来告诉程序您希望其确切执行的操作:要调用的析构函数(以及是否调用),要调用的其他清理函数,要返回的值等等。
std :: terminate是更高级别的抽象:(运行时或您自己)调用它来指示程序中发生了错误,并且由于某种原因无法通过引发异常进行处理。当异常机制本身发生错误时,通常会发生这种情况,但是当您不希望程序继续超出给定错误时,可以随时使用它。当我在帖子中调用std :: terminate时,我整理了情况的完整列表。没有指定std :: terminate做什么,因为您可以控制它。您可以通过注册任何功能来配置行为。您的局限性在于该函数无法返回到错误站点,并且无法通过异常退出,但是从技术上讲,您甚至可以在内部启动消息泵。有关您可以在其中执行的有用操作的列表,请参阅我的其他文章。
特别要注意,在由于无法处理引发的异常而调用std :: terminate的上下文中,std :: terminate被视为异常处理程序,您可以检查异常是什么并使用C ++进行检查11使用std :: rethrow_exception和std :: current_exception。这都是我的帖子。
如果您的程序是多线程的,则调用exit()
很可能会导致崩溃,因为std::thread
将尝试在不退出线程的情况下破坏全局/静态对象。
如果要返回错误代码并正常退出程序(或多或少),请调用quick_exit()
多线程程序。对于异常终止(无法指定错误代码),abort()
或std::terminate()
可以调用。
注意:MSVC ++直到2015版才支持quick_exit()。
当发生无法处理的异常时,将自动调用终止()。默认情况下,terminate()调用abort()。您可以使用set_terminate()函数设置自定义句柄。
abort()发送SIGABRT信号。
exit()不一定是一件坏事。它成功退出应用程序,并以LIFO顺序调用atexit()函数。我通常不会在C ++应用程序中看到这种情况,但是,在很多基于Unix的应用程序中却会看到它在最后发送退出代码的情况。通常,exit(0)表示应用程序已成功运行。