Overview
When an exception is unhandled, it leads to termination of the application. The following discusses setting up custom handlers that's called before before termination.
Details
The following discusses setting up terminate_handler which is called before application termination and others. Note that some of these are deprecated by later versions of C++ standard.
terminate()
terminate() can be called explicitly by an application code to terminate the application. It's also called internally by C++ runtime for example, in case of uncaught exceptions when no catch handler can be found for a thrown exception, or for some other exceptional circumstance that makes impossible to continue the exception handling process.
By default, the terminate handler calls abort. But this behavior can be redefined by calling set_terminate() call.
Syntax
typedef void ( *terminate_handler )();
The following discusses the functions in detail.
Name | Description |
---|---|
terminate_handler get_terminate() | Returns the current terminate handler function set by previous set_terminate() function. If it was never set, nullptr might be returned or a function pointer to a default terminate_handler. |
terminate_handler set_terminate (terminate_handler f) | Sets f as the terminate handler function and returns previously set terminate_handler or a nullptr. |
void terminate() | Calls the current terminate handler or call the default terminate_handler which calls abort(). |
/*prints inside terminate handler */ set_terminate([]() { cerr << "inside terminate handler" << flush; abort(); }); try { throw 1; } catch(...) { throw; }
uncaught_exception()
uncaught_exception() can be called to determine if stack unwinding is happening. What it means is, after a exception is thrown, if it's not handled in a catch block or unexpected or terminate handler, the return value will be true. Otherwise it will return false.
struct Foo { char id{'?'}; int count = uncaught_exceptions(); ~Foo() { count == uncaught_exceptions() ? cout << id << ".~Foo() called normally\n" : cout << id << ".~Foo() called during stack unwinding\n"; } }; /*prints Exception thrown g.~Foo() called during stack unwinding f.~Foo() called normally Exception caught: test exception */ Foo f{'f'}; try { Foo g{'g'}; cout << "Exception thrown\n"; throw runtime_error("test exception"); } catch (const exception& e) { cerr << "Exception caught: " << e.what() << '\n'; }
unexpected()
unexpected() is called by the C++ runtime when a dynamic exception specification is violated: an exception is thrown from a function whose exception specification forbids exceptions of this type. unexpected() may also be called directly from the program.
In either case, unexpected() calls the currently installed unexpected_handler. The default unexpected_handler calls terminate().
void myunexpected () { cerr << "unexpected handler called\n"; throw; } void myfunction () throw (int,bad_exception) { throw 'x'; // throws char (not in exception-specification) } set_unexpected (myunexpected); try { myfunction(); } catch (int) { cerr << "caught int\n"; } catch (bad_exception be) { cerr << "caught bad_exception\n"; } catch (...) { cerr << "caught some other exception\n"; }
No comments:
Post a Comment