中止,终止或退出?
这三者之间有什么区别,如果我不能正确处理exception,我该如何结束程序?
我的build议是不会使用任何一个。 相反,在main()中捕获你不能处理的exception,并简单地从那里返回。 这意味着你可以保证堆栈展开正确,所有的析构函数都被调用。 换一种说法:
int main() { try { // your stuff } catch( ... ) { return 1; // or whatever } }
-
放弃指示程序结束“exception”,并引发POSIX信号SIGABRT,这意味着你已经为该信号注册的任何处理程序都将被调用,尽pipe在这两种情况下程序仍然会在字后面终止。 通常情况下,你可以在C程序中使用
abort
来退出一个意外的错误,这个错误很可能是程序中的错误,而不是错误的input或者networking故障。 例如,如果发现数据结构中有一个NULL指针,则逻辑上不会发生这种情况。 -
退出表示程序的“正常”结束,尽pipe这可能仍然表示失败(但不是错误)。 换句话说,如果用户input了无法parsing的input,或者无法读取文件,则可能会
exit
。 退出代码0表示成功。exit
还可以select调用处理程序在程序结束之前。 这些注册与atexit
和on_exit
函数。 -
std :: terminate是在有未处理的exception时在C ++程序中自动调用的东西。 这实际上是C ++等价于
abort
,假设您通过抛出exception来报告所有exception错误。 这将调用由std::set_terminate
函数设置的处理程序,默认情况下该函数会简单地调用abort
。
在C ++中,您通常希望避免调用abort
或exit
错误,因为抛出exception并让代码进一步调用堆栈决定是否结束程序是合适的。 无论您是否使用exit
来获得成功都是一个情况 – 无论是否在除了main
的return语句之外的其他地方结束程序都是有意义的。
std::terminate
应该被认为是最后的错误报告工具,即使在C ++中也是如此。 std::terminate
的问题是终止处理程序无法访问未处理的exception,因此无法确定它是什么。 try { } catch (std::exception& ex) { }
块中,通常情况下,将整个main包装起来会好得多。 至less可以报告更多关于从std::exception
派生的std::exception
(尽pipe当然,不会从std::exception
派生的std::exception
仍然会被处理)。
在try { } catch(...) { }
包装main
的主体并不比设置终止处理程序更好,因为您再次无法访问有问题的exception。 编辑:根据Neil Butterworth的回答,在这种情况下堆栈被解开是一个好处,对于未处理的exception来说(这有点令人惊讶)是不正确的。
std :: abort和std :: exit(以及更多:std :: _ Exit,std :: quick_exit)只是更低级别的函数。 你使用它们来告诉程序你想要它做什么:什么析构函数(如果)调用,还有什么其他清理函数要调用,返回什么值等等。
std :: terminate是一个更高层次的抽象:它被调用(通过运行时或者你)来表示程序中发生了一个错误,并且由于某种原因不能通过抛出exception来处理。 当exception机制本身发生错误时,通常会出现这种情况,但是如果您不希望程序继续超出给定的错误,则可以随时使用它。 我在我的post中调用了 std :: terminate被调用的完整列表。 它没有指定什么std :: terminate做,因为你在控制它。 您可以通过注册任何function来configuration行为。 你的限制是函数不能返回错误站点,也不能通过exception退出,但是从技术上讲,你甚至可以启动你的消息泵。 有关您可以在里面做的有用事情的列表,请参阅我的其他post 。
特别要注意的是std :: terminate在上下文中被认为是一个exception处理程序,在这个上下文中,由于抛出的exception无法被处理,std :: terminate被调用,你可以检查exception是什么,并用C ++ 11使用std :: rethrow_exception和std :: current_exception。 这一切都在我的职位 。
quick_exit() !
如果你的程序是multithreading的,那么调用exit()
将最有可能导致崩溃,因为全局/静态std::thread
对象将被试图在不退出其线程的情况下被破坏。
如果您想要返回错误代码并正常退出程序(或多或less),请在multithreading程序中调用quick_exit()
。 对于exception终止(不可能指定错误代码),可以调用abort()
或std::terminate()
。
注意:在版本2015之前, quickexec()不被MSVC ++所支持 。
-
当发生无法处理的exception时,会自动调用terminate()。 默认情况下,terminate()调用abort()。 您可以使用set_terminate()函数设置自定义句柄。
中止()发送SIGABRT信号。
exit()不一定是坏事。 它成功退出应用程序,并以LIFO顺序调用atexit()函数。 我通常不会在C ++应用程序中看到这一点,但是,我在许多基于unix的应用程序中看到了它,它在最后发送退出代码。 通常退出(0)表示应用程序成功运行。
- 终止会让你有可能注册被调用时会发生什么。 应该是其他两个之一。
- 退出是允许指定退出状态的正常退出。 由at_exit()注册的处理程序运行
- 放弃是一个exception退出。 唯一运行的是SIGABRT的信号处理程序。