What's the difference between those three, and how shall I end program in case of exception which I can't handle properly?
- 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.
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:
int main() {
try {
// your stuff
}
catch( ... ) {
return -1; // or whatever
}
}
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
abortin 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 mightabortif 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
exitwith 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.exitalso optionally calls handlers before it ends the program. These are registered with theatexitandon_exitfunctions.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 thestd::set_terminatefunction, which by default simply callsabort.
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.
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(1) indicates a successful run of the application.