std::中止和std::退出(以及更多:std::_Exit、std::quick_exit)只是较低级别的函数。你用它们来告诉程序你想让它做什么:调用什么析构函数(和if)、调用什么其他清除函数、返回什么值等。 std::terminate是更高级别的抽象:它被调用(由运行时或您自己调用)来指示程序中出现了错误,并且由于某种原因,无法通过抛出异常来处理。通常,当异常机制本身出现错误时,需要这样做,但是当您不希望程序在给定错误后继续运行时,可以随时使用它。我编译了调用in my post时std::terminate的完整情况列表。没有指定std::terminate做什么,因为您可以控制它。您可以通过注册任何函数来配置行为。您的限制是函数不能返回到错误站点,也不能通过异常退出,但从技术上讲,您甚至可以在内部启动消息泵。要了解您可以在内部做的有用事情的列表,请参阅my other post。 特别要注意的是,当std::terminate被调用时,它会被视为一个异常处理程序,因为抛出了一个无法处理的异常,你可以检查这个异常是什么,并使用C++11中的std::rethrow_exception和std::current_exception来检查它。
我的天! 如果你的程序是多线程的,那么调用exit()很可能会导致崩溃,因为全局/静态std::thread对象将在不退出它们的线程的情况下试图析构。 如果你想返回一个错误代码并正常地退出程序(或多或少),在多线程程序中调用quick_exit()。对于异常终止(不可能指定错误代码),可以调用abort()或std::terminate()。 注:quick_exit() has not been supported by MSVC++至2015版。
6条答案
按热度按时间xu3bshqb1#
*abort表示程序“异常”结束,并引发POSIX信号SIGABRT,这意味着您为该信号注册的任何处理程序都将被调用,尽管在这两种情况下程序仍然会终止。通常您会在C程序中使用
abort
来退出意外错误情况,这种错误可能是程序中的bug。而不是错误的输入或网络故障。例如,如果发现一个数据结构中有一个NULL指针,而在逻辑上不应该发生这种情况,则可以使用abort
。*exit表示程序“正常”结束,尽管这可能仍表示失败换句话说,如果用户提供了无法解析的输入,您可能会得到
exit
错误代码,或无法读取文件。退出代码0表示成功。exit
在结束程序之前还可以选择调用处理程序。这些寄存器使用atexit
和on_exit
函数注册。*std::terminate是C程序中出现未处理异常时自动调用的函数。这基本上是C中
abort
的等价函数,假设您通过抛出异常来报告所有异常错误。这将调用由std::set_terminate
函数设置的处理函数,默认情况下,std::set_terminate
函数只调用abort
。在C中,您通常希望避免在出错时调用
abort
或exit
,因为您最好抛出一个异常,让调用堆栈中更上层的代码来决定是否结束程序。无论在main
中的return语句之外的某个地方结束程序是否有意义。std::terminate
应该被看作是最后的错误报告工具,即使在C中也是如此。std::terminate
的问题是终止处理程序 * 不 * 能够访问未处理的异常,因此无法判断它是什么。通常最好将整个main封装在一个try { } catch (std::exception& ex) { }
块中。至少这样,您可以报告更多关于从std::exception
派生的异常的信息(当然,不是从std::exception
派生的异常仍然会以未处理结束)。将
main
的主体 Package 在try { } catch(...) { }
中并不比设置一个终止处理程序好多少,因为你同样无法访问所讨论的异常。当一个异常完全未被捕获时,堆栈展开是否完成是由实现定义的,所以如果你需要有保证的堆栈展开,这将是一种获得它的方法。unguejic2#
std::中止和std::退出(以及更多:std::_Exit、std::quick_exit)只是较低级别的函数。你用它们来告诉程序你想让它做什么:调用什么析构函数(和if)、调用什么其他清除函数、返回什么值等。
std::terminate是更高级别的抽象:它被调用(由运行时或您自己调用)来指示程序中出现了错误,并且由于某种原因,无法通过抛出异常来处理。通常,当异常机制本身出现错误时,需要这样做,但是当您不希望程序在给定错误后继续运行时,可以随时使用它。我编译了调用in my post时std::terminate的完整情况列表。没有指定std::terminate做什么,因为您可以控制它。您可以通过注册任何函数来配置行为。您的限制是函数不能返回到错误站点,也不能通过异常退出,但从技术上讲,您甚至可以在内部启动消息泵。要了解您可以在内部做的有用事情的列表,请参阅my other post。
特别要注意的是,当std::terminate被调用时,它会被视为一个异常处理程序,因为抛出了一个无法处理的异常,你可以检查这个异常是什么,并使用C++11中的std::rethrow_exception和std::current_exception来检查它。
amrnrhlw3#
我的天!
如果你的程序是多线程的,那么调用
exit()
很可能会导致崩溃,因为全局/静态std::thread
对象将在不退出它们的线程的情况下试图析构。如果你想返回一个错误代码并正常地退出程序(或多或少),在多线程程序中调用
quick_exit()
。对于异常终止(不可能指定错误代码),可以调用abort()
或std::terminate()
。注:quick_exit() has not been supported by MSVC++至2015版。
pkln4tw64#
abort()发送SIGABRT信号。
exit()不一定是坏事。它成功地退出应用程序,并以LIFO顺序调用atexit()函数。我通常在C++应用程序中看不到这种情况,但是,我在许多基于unix的应用程序中确实看到了它,它在最后发送一个退出代码。通常exit(0)表示应用程序成功运行。
62lalag45#
gv8xihay6#
我的建议是不要使用它们中的任何一个。相反,
catch
表示你不能在main()
中处理的异常,并简单地从return
开始。这意味着你可以保证堆栈展开正确发生,并且所有析构函数都被调用。换句话说: