C++ 中止、终止或退出?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2820285/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
abort, terminate or exit?
提问by There is nothing we can do
What's the difference between those three, and how shall I end program in case of exception which I can't handle properly?
这三者之间有什么区别,如果我无法正确处理异常,我该如何结束程序?
采纳答案by Daniel
My advice would be not to use any of them. Instead, catch
the exceptions you can't handle in main()
and simply return
from there. This means that you are guaranteed that stack unwinding happens correctly and all destructors are called. In other words:
我的建议是不要使用它们中的任何一个。取而代之的catch
是您无法处理的异常,main()
并且只能return
从那里处理。这意味着您可以保证堆栈展开正确发生并调用所有析构函数。换句话说:
int main() {
try {
// your stuff
}
catch( ... ) {
return 1; // or whatever
}
}
回答by Tyler McHenry
abortindicates "abnormal" end to the program, and raises the the POSIX signal SIGABRT, which means that any handler that you have registered for that signal will be invoked, although the program will still terminate afterwords in either case. Usually you would use
abort
in a C program to exit from an unexpected error case where the error is likely to be a bug in the program, rather than something like bad input or a network failure. For example, you mightabort
if a data structure was found to have a NULL pointer in it when that should logically never happen.exitindicates a "normal" end to the program, although this may still indicate a failure (but not a bug). In other words, you might
exit
with an error code if the user gave input that could not be parsed, or a file could not be read. An exit code of 0 indicates success.exit
also optionally calls handlers before it ends the program. These are registered with theatexit
andon_exit
functions.std::terminateis what is automatically called in a C++ program when there is an unhandled exception. This is essentially the C++ equivalent to
abort
, assuming that you are reporting all your exceptional errors by means of throwing exceptions. This calls a handler that is set by thestd::set_terminate
function, which by default simply callsabort
.
abort表示程序的“异常”结束,并引发 POSIX 信号 SIGABRT,这意味着您为该信号注册的任何处理程序都将被调用,尽管在任何一种情况下程序仍将终止后记。通常,您会
abort
在 C 程序中使用以退出意外错误情况,其中错误可能是程序中的错误,而不是诸如错误输入或网络故障之类的错误。例如,您可能会abort
发现数据结构中有一个 NULL 指针,而这在逻辑上是永远不会发生的。exit表示程序的“正常”结束,尽管这可能仍然表示失败(但不是错误)。换句话说,
exit
如果用户提供了无法解析的输入,或者无法读取文件,您可能会收到错误代码。退出代码 0 表示成功。exit
还可以选择在结束程序之前调用处理程序。这些是用atexit
和on_exit
函数注册的。std::terminate是在出现未处理异常时在 C++ 程序中自动调用的内容。这本质上是 C++ 等价于
abort
,假设您通过抛出异常报告所有异常错误。这将调用由函数设置的处理程序,std::set_terminate
默认情况下它只调用abort
.
In C++, you usually want to avoid calling abort
or exit
on error, since you're better off throwing an exception and letting code further up the call stack decide whether or not ending the program is appropriate. Whether or not you use exit
for success is a matter of circumstance - whether or not it makes sense to end the program somewhere other than the return statement in main
.
在 C++ 中,您通常希望避免调用abort
或exit
出错,因为最好抛出异常并让代码进一步调用堆栈来决定是否结束程序。您是否exit
成功使用是一个环境问题 - 在main
.
std::terminate
should be considered a last-ditch error reporting tool, even in C++. The problem with std::terminate
is that the terminate handler does nothave access to the exception that went unhandled, so there's no way to tell what it was. You're usually much better off wrapping the entirety of main in a try { } catch (std::exception& ex) { }
block. At least then you can report more information about exceptions that derived from std::exception
(although of course exceptions that do not derive from std::exception
would still end up unhandled).
std::terminate
应该被视为最后的错误报告工具,即使在 C++ 中也是如此。问题std::terminate
在于终止处理程序无权访问未处理的异常,因此无法确定它是什么。通常最好将整个 main 包装在一个try { } catch (std::exception& ex) { }
块中。至少,您可以报告更多有关源自的异常的信息std::exception
(当然,并非源自的异常std::exception
最终仍将无法处理)。
Wrapping the body of main
in try { } catch(...) { }
isn't much better than setting a terminate handler, because again you have no access to the exception in question. Edit:Per Neil Butterworth's answer, there is a benefit in that the stack is unwound in this case, which is (somewhat surprisingly) not true for an unhandled exception.
包装main
in的主体try { } catch(...) { }
并不比设置终止处理程序好多少,因为您再次无法访问有问题的异常。编辑:根据尼尔巴特沃斯的回答,有一个好处是在这种情况下堆栈被解开,这对于未处理的异常来说(有点令人惊讶)不是真的。
回答by Andrzej
std::abort and std::exit (and more: std::_Exit, std::quick_exit) are just lower level functions. You use them to tell the program what you want it to do exactly: what destructors (and if) to call, what other clean-up functions to call, what value to return, etc.
std::abort 和 std::exit(以及更多:std::_Exit、std::quick_exit)只是较低级别的函数。你用它们来告诉程序你想要它做什么:要调用什么析构函数(和 if),要调用什么其他清理函数,要返回什么值等。
std::terminate is a higher level abstraction: it is called (by either run-time or you) to indicate that an error in the program occurred and that for some reason it is not possible to handle by throwing an exception. The necessity for that typically occurs when error occurs in the exception mechanism itself, but you can use it any time when you do not want your program to continue beyond the given error. I compiled the full list of situations when std::terminate is called in my post. It is not specified what std::terminate does, because you are in control of it. You can configure the behavior by registering any functions. The limitations you have are that the function cannot return back to the error site and it cannot exit via an exception, but technically you can even start your message pump inside. For the list of useful things that you can do inside, see my other post.
std::terminate 是更高级别的抽象:它被调用(由运行时或您)以指示程序中发生错误并且由于某种原因无法通过抛出异常来处理。当异常机制本身发生错误时,通常会发生这种情况,但是当您不希望程序继续超出给定错误时,您可以随时使用它。我编译了在我的帖子中调用 std::terminate 的完整情况列表. 没有指定 std::terminate 做什么,因为您可以控制它。您可以通过注册任何函数来配置行为。您的限制是该函数不能返回到错误站点,也不能通过异常退出,但从技术上讲,您甚至可以在内部启动消息泵。有关您可以在里面做的有用事情的列表,请参阅我的另一篇文章。
In particular, note that std::terminate is considered an exception handler in contexts where std::terminate is called due to a thrown exception that could not be handled, and you can check what the exception was and inspect it by using C++11 using std::rethrow_exception and std::current_exception. It is all in my post.
特别注意,在 std::terminate 由于无法处理的抛出异常而被调用的上下文中,std::terminate 被视为异常处理程序,您可以检查异常是什么并使用 C++ 检查它11 使用 std::rethrow_exception 和 std::current_exception。这都在我的帖子里。
回答by Serge Rogatch
If your program is multi-threaded, then calling exit()
will most likely result in a crash because global/static std::thread
objects will be attempted to destruct without exiting their threads.
如果您的程序是多线程的,那么调用exit()
很可能会导致崩溃,因为std::thread
将尝试在不退出线程的情况下破坏全局/静态对象。
If you want to return an error code and exit the program (more or less) normally, call quick_exit()
in multi-threaded programs.
For abnormal termination (without a possibility for you to specify the error code), abort()
or std::terminate()
can be called.
如果要返回错误代码并正常退出程序(或多或少),请调用quick_exit()
多线程程序。对于异常终止(您无法指定错误代码),abort()
或者std::terminate()
可以调用。
Note: quick_exit() has not been supported by MSVC++until version 2015 .
注意:在2015 版之前,MSVC++ 不支持 quick_exit()。
回答by AProgrammer
- terminate leaves you the possibility to register what will happen when it is called. Should be one of the other two.
- exit is a normal exit allowing to specify an exit status. Handlers registered by at_exit() are run
- abort is an abnormal exit. The only thing which is ran is the signal handler for SIGABRT.
- 终止使您可以注册调用时会发生什么。应该是另外两个之一。
- exit 是允许指定退出状态的正常退出。运行由 at_exit() 注册的处理程序
- abort 是异常退出。唯一运行的是 SIGABRT 的信号处理程序。
回答by Daniel
terminate() is automatically called when an exception occurs that cannot be handled. By default, terminate() calls abort(). You can set a custom handle with set_terminate() function.
abort() sends the SIGABRT signal.
exit() is not necessarily a bad thing. It successfully exits the application, and calls atexit() functions in LIFO order. I don't normally see this in C++ applications, however, I do see it in many unix based applications where it sends an exit code at the end. Usually a exit(0) indicates a successful run of the application.
当发生无法处理的异常时,会自动调用 terminate()。默认情况下,terminate() 调用 abort()。您可以使用 set_terminate() 函数设置自定义句柄。
abort() 发送 SIGABRT 信号。
exit() 不一定是坏事。它成功退出应用程序,并以 LIFO 顺序调用 atexit() 函数。我通常不会在 C++ 应用程序中看到它,但是,我确实在许多基于 Unix 的应用程序中看到它,它在最后发送退出代码。通常 exit(0) 表示应用程序成功运行。