Tyl*_*nry 139
abort表示程序的"异常"结束,并引发POSIX信号SIGABRT,这意味着您已经为该信号注册的任何处理程序都将被调用,尽管在任何一种情况下程序仍然会在字后面终止.通常,您将abort在C程序中使用以退出意外错误情况,其中错误可能是程序中的错误,而不是输入错误或网络故障.例如,abort如果发现数据结构在其中具有NULL指针,则逻辑上永远不会发生这种情况.
exit表示程序的"正常"结束,尽管这可能仍然表示失败(但不是错误).换句话说,exit如果用户提供了无法解析的输入,或者无法读取文件,则可能会显示错误代码.退出代码为0表示成功.exit也可以选择在程序结束前调用处理程序.这些是在atexit和on_exit函数中注册的.
std :: terminate是存在未处理异常时在C++程序中自动调用的内容.这基本上是C++的等价物abort,假设您通过抛出异常来报告所有异常错误.这会调用由函数设置的处理程序,std::set_terminate默认情况下只调用该函数abort.
在C++中,您通常希望避免调用abort或exit出错,因为您最好抛出异常并让调用堆栈中的代码进一步决定是否结束该程序.你是否exit用于成功是一个环境问题 - 是否有必要在除了返回声明之外的某个地方结束程序main.
std::terminate应该被认为是最后一个错误报告工具,即使在C++中也是如此.问题std::terminate是终止处理程序无法访问未处理的异常,因此无法确定它是什么.你通常会更好地将整个主要包装在一个try { } catch (std::exception& ex) { }块中.至少那时你可以报告有关派生的异常的更多信息std::exception(尽管当然不会派生的异常std::exception仍会以未处理的方式结束).
包装mainin 的主体try { } catch(...) { }并不比设置终止处理程序好多,因为再次无法访问相关的异常.编辑:根据Neil Butterworth的回答,有一个好处是在这种情况下堆栈是解开的,对于未处理的异常(有些令人惊讶地)是不正确的.
And*_*zej 14
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.这一切都在我的帖子中.
Ser*_*tch 10
如果您的程序是多线程的,那么调用exit()很可能会导致崩溃,因为全局/静态std::thread对象将在不退出其线程的情况下尝试销毁.
如果要返回错误代码并正常退出程序(或多或少),请调用quick_exit()多线程程序.对于异常终止(无法指定错误代码),abort()或者std::terminate()可以调用.
注意:直到2015版本,MSVC++才支持quick_exit().
当发生无法处理的异常时,会自动调用 terminate()。默认情况下,terminate() 调用 abort()。您可以使用 set_terminate() 函数设置自定义句柄。
abort() 发送 SIGABRT 信号。
exit() 不一定是坏事。它成功退出应用程序,并以 LIFO 顺序调用 atexit() 函数。我通常不会在 C++ 应用程序中看到它,但是,我确实在许多基于 Unix 的应用程序中看到它,它在最后发送退出代码。通常 exit(0) 表示应用程序成功运行。
小智 5
我的建议是不要使用它们中的任何一个.相反,捕获你在main()中无法处理的异常,然后从那里返回.这意味着您可以保证堆栈展开正确并且所有析构函数都被调用.换一种说法:
int main() {
try {
// your stuff
}
catch( ... ) {
return 1; // or whatever
}
}
Run Code Online (Sandbox Code Playgroud)