What\'s the difference between those three, and how shall I end program in case of exception which I can\'t handle properly?
abort indicates "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 might abort
if a data structure was found to have a NULL pointer in it when that should logically never happen.
exit indicates 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 the atexit
and on_exit
functions.
std::terminate is 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 the std::set_terminate
function, which by default simply calls 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
.
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 not have 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).
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.