I have a non-void function which returns a value to be used as an input of a class constructor, but there is a possibility for that value not to be available, so I want to return the value in case of success or just terminate (std::terminate()) the application in case of failure before the function return.
Since std::terminate is called by the runtime according to https://en.cppreference.com/w/cpp/error/terminate, am I obliged to throw an exception and let the runtime decide whether the program is terminated or not?
What about the following warning I read in a simple test I just performed? "terminate called without an active exception"
Am I going in a stupid way?
Thanks for your insights in advance!
... I obliged to throw an exception and let the runtime decide whether the program is terminated or not?
It is up to you. If you want to be able for an exception to be caught somewhere up the call stack then you should throw an exception. In cases you want to terminate because there is no way to recover then calling std::terminate is fine. Just consider that if you throw an exception which is not caught then the program terminates anyhow, so you can choose to either catch it or not, while std::terminate terminates always.
The same page that you linked to, in your question, also has the following statement:
std::terminate() may also be called directly from the program.
Related
Is it ok to just call throw; from constructor if something goes awry, and you have no idea how to recover?
The idea is to let the app crash with a dump, as the state is unknown. Or should you always specify an argument?
From MSDN I only found that it rethrows if there is no argument, but no idea what happens if there is no initial exception to rethrow.
No. throw; is a special syntax that re-throws current exception. It only makes sense inside catch blocks (or code called from one) to continue propagating the exception.
Just use:
#include <stdexcept>
...
throw std::runtime_error("some description");
or even just
throw "some description";
but the later is uglier to handle and just generally frowned upon.
If there's no exception currently being processed throw; will lead to terminate() being called immediately and that will end your program abnormally. That is not very convenient - you'll have less information about what happened compared to throwing a meaningful exception. You could have thrown a meaningful exception, catch it at the top level (like main()), write some diagnostics and then end the program.
An ASSERT might make your life easier to dignose what's going wrong
While technically you can call it, it won't do what you'd like.
The simplest solution is to call throw std::runtime_exception("thrown from Foo");, which at the same time gives some feedback about what was going on.
When you say "no idea how to recover" what you mean I presume is that at this point you do not know how to handle the error?
Perhaps you are not getting the point of exceptions. You throw information: that the exception occurred and why. The call-stack is then unwound to the point where it can be handled. At that point in the code we know how, if possible, to recover.
Technically, you can do that because throw without argument and without an active exception just calls terminate() which by default calls abort(). I prefer calling abort() directly, it requires less cognitive effort to recognize what is going on.
I have some technical questions. In this function:
string report() const {
if(list.begin() == list.end()){
throw "not good";
}
//do something
}
If I throw the exception what is going on with the program? Will my function terminate or will it run further? If it terminates, what value will it return?
If you throw an exception, all functions will be exited back to the point where it finds a try...catch block with a matching catch type. If your function isn't called from within a try block, the program will exit with an unhandled exception.
Check out https://isocpp.org/wiki/faq/exceptions for more info.
It will basically go up the stack until it finds an exception handler; if it gets to the end of the stack without finding one, your program will crash. If it does find one, it will rewind the stack up that point, run the handler, and continue with the code after the handler block, however far up your stack that may be.
You can get all sorts of details about C++'s exception handling mechanism through Google. Here's a head start.
Since you're not catching the exception within the context of the function, the function will terminate and the stack will be unwound as it looks for an exception handler (a catch block that would match either string, or the generic catch(...)). If it doesn't find one, your program will terminate.
Your function will terminate immediately, and it won't return anything. If there are no catch statements catching the exception "up the call chain", your application will terminate.
It won't return, it will in fact terminate and reach the "nearest" (call-stack-wise) try...catch block.
If none is found, most of the time the program just exits, on some platforms the error can be printed, I don't know the specifics of that though (and most likely only the ones derived from std::exception).
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. There is at least one benefit, though: whether stack unwinding is done when an exception goes completely uncaught is implementation defined, so if you need guaranteed stack unwinding, this would be a way to get that.
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::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.
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.
quick_exit() !
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.
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.
Note: quick_exit() has not been supported by MSVC++ until version 2015 .
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 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
}
}
I want to use boost::asio but I don't want boost to throw exceptions, because in my environment exceptions must not be raised.
I've encountered BOOST_NO_EXCEPTIONS but the documentation says that callers of throw_exception can assume that this function never returns.
But how can a user supplied function not return? What replacement function would I need to insert here? Do I have to terminate the process in case boost code wants to throw an exception?
Well, what do you want to do on error condition? BOOST_NO_EXCEPTION does not magically make Boost source code use alternative mechanism of propagating error back to callers. So, you either print an error to stderr and die, or you longjmp all the way to the top -- leaking whatever resources the functions presently on the call stack might have allocated.
Either you terminate the process or you goto a something like a global error handler using longjmp which you've previously defined with setjmp.
You seemed to have misunderstood the meaning of BOOST_NO_EXCEPTIONS, it only gives you a chance to bailout in the way you desire in a consistent manner.
The execution has entered a state where it can no more proceed, that is when exception is thrown, so if the user defined throw_exception returns then it is logical to think that the behavior is undefined.
I am not getting why if there is an active exception then if an exception is raised again, it leads to termination of program. Could someone explain?
What is it suppose to do? It can't "double catch" or anything, nor does it make sense to simply ignore one. The standard specifies that if, during stack unwinding, another exception escapes, then terminate shall be called.
There is more discussion in the C++ FAQ. One "solution" is to wrap your destructor code in a try/catch block, and simply don't let exceptions escape.
Another is to come up with some sort of custom exception chaining scheme. You'd do the above, but instead of ignoring an exception, you would append it to the currently thrown exception, and at the catch site handle both by hand.
The best solution, I think, it to try to remove the exceptional code from your destructor.
The reason is simple... if an exception is thrown during exception propagation, then which exception should be propagated? The original exception or the new exception? If the new exception is propagated and then handled, how will the program know that the other exception occurred? Or will the original exception be ignored? This and many other complications lead to the simple rule that only one exception may be propagated at a time, and multiple failures will result in the application being terminated.
Quoth the standard (15.2.3):
The process of calling destructors for automatic objects constructed on the path from a try block to a throw-expression is called ``stack unwinding.'' [Note: If a destructor called during stack unwinding exits with an exception, terminate is called (except.terminate). So destructors should generally catch exceptions and not let them propagate out of the destructor.
--- end note]
Basically C++ (as most other popular programming languages) has no good support for handling multiple errors using exceptions. Exceptions, as a mechanism, is simply deficient in that respect.
The FAQ has some suggestion on How to handle a destructor that fails?
Stroustroup has this to say on the matter (TCPL 14.7):
The reason for terminate() is that exception handling must occasionally be abandoned for less subtle error-handling techniques. For example, terminate() could be used to abort a process or maybe to re-initialize a system. The intent is for terminate() to be a drastic measure to applied when the error-recovery strategy implemented by the exception-handling mechanism has failed and it is time to go to another level of a fault tolerance strategy.
See also previous related discussion on SO: basically any question about exceptions and destructors.
This post has an explanation of the problem:
http://web.tiscali.it/fanelia/cpp-faq-en/exceptions.html#faq-17.3
When you throw an exception, it keeps unwinding the stack until it reaches an appropriate catch block. As part of the stack unwinding process, destructors are called for every object in each frame's scope.
Now, when a destructor throws an exception in this case, there's a dilemma -- which catch block is the program supposed to stop at? The original exception, or the new exception? Either way, there's an unprocessed exception involved.
Program's aren't good at making decisions like this, so the standard says it won't even try to resolve the issue and just gives up.
Check out the FAQ-Lite entry explaining this exact situation for further details.
Item 8 of Effective C++ says that you shouldn't ever allow an exception to leave a destructor.