I have seen many code examples where the unexpected() function handler (as set by set_unexpected) itself throws an exception.
What is the point of doing that? I thought unexpected() was the exception catcher of last resort. Who will catch the exception thrown by the unexpected() function handler?
I'm currently following C++ core guidelines setting all destructors in my code to be noexcept. Some of my destructors may potentially throw exceptions - in that case I would like the program to crash and provide me with details on what caused the crash. Setting the noexcept specifier on the destructor will call std::terminate() which in turns invoke the default terminate_handler. The default terminate_handler will print the exception which was fired inside the destructor. This is great in the case in which the throwing destructor was not called while another exception was being thrown. In that case I would like the terminate_handler to print both exceptions so I can know what triggered the error handling path in the first place.
The problem is I can't seem to find a way in the standard library to get the uncaught exception. There's a std::current_exception() function which gets the exception being handled and std::uncaught_exceptions() which only gets the number of uncaught exception. I would like to get an std::exception_ptr or something to the uncaught exceptions. Is that possible?
See: https://www.danielseither.de/blog/2013/12/globally-handling-uncaught-exceptions-and-signals-in-c/
std::exception_ptr exptr = std::current_exception();
try {
std::rethrow_exception(exptr);
}
catch (std::exception &ex) {
std::fprintf(stderr, "Terminated due to exception: %s\n", ex.what());
}
The following code terminates abnormally as no object is explicitly thrown. What is thrown by throw statement in the following code?
int main()
{
try{
cout<<"try";
throw ;
}
catch(...){
cout<<"catch";
}
return 0;
}
throw without an argument should only be used inside a catch statement, to rethrow the caught exception object. You code tries to use it outside the catch statement - instead you should pick a type to throw, if in doubt it's not unreasonable to start with std::runtime_error. For more options, see here. You can also throw your own types, but it's usually a good idea to derive them from one of the Standard-library provided types so client code has a better chance at specifying appropriate handling for all logically similar errors, rather than having to catch and handle them separately and being constantly updated for each new possible error.
FWIW, the Standard says in 15.1/9:
If no exception is presently being handled, executing a throw-expression with no operand calls std::terminate().
So very explicitly, the answer to "What is thrown..." is that no throwing is done, and std::terminate is called instead.
So the question is: "What happens when I throw outside a catch block?" The answer to this can be found in its documentation:
Rethrows the currently handled exception. Abandons the execution of the current catch block and passes control to the next matching exception handler (but not to another catch clause after the same try block: its compound-statement is considered to have been 'exited'), reusing the existing exception object: no new objects are made. This form is only allowed when an exception is presently being handled (it calls std::terminate if used otherwise). The catch clause associated with a function-try-block must exit via rethrowing if used on a constructor.
Emphasize mine.
In the application I am writing, I make usage of exceptions for most of my error handling. I've not defined my own exception classes just yet, I merely did the following:
namespace Mage {
typedef std::exception Exception;
}
This way I won't have to change all of my code when I define my own type later which should use the same interface.
That said, any exception crashes my application. Taking the above definition in mind, why would this crash?
void Mage::Root::initialize(Mage::String& p_log) {
// initialize GLFW and GLEW.
if (!glfwInit()) {
throw new Mage::Exception("failed to initialize OpenGL");
return;
} else m_GLFWInitialized = true;
Whether I remove or keep 'new', it would still crash. Am I missing something? I've looked up tutorials but those don't get me any wiser.
I also catch the error right here:
try {
MAGE_ROOT.initialize(Mage::String("Mage.log"));
} catch (Mage::Exception& e) {
std::cerr << e.what() << std::endl;
}
The crash I'm getting is:
Debug Error!
Program: ...sual Studio 2010\Project\Mage3D\Binaries\Debug\Test.exe
R6010
- abort() has been called
(Press Retry to debug application)
The problem is that you are not catching your exception.
I wasn't aware you -have- to catch the exception (from the comments)
Yes, you have to. If you do not catch a thrown exception, std::terminate() will be called. This is the intended behavior: exceptions exist to prevent programmers from forgetting about error handling.
This said, I suggest:
throwing by value;
catching by reference
For instance:
void foo()
{
// ...
throw std::logic_error("Error!");
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Throw by value (std::logic_error derives from std::exception)
// ...
}
void bar()
{
try
{
// ...
foo();
// ...
}
catch (std::exception& e)
^^^^^^^^^^^^^^^
// Catch by reference
{
std::cout << e.what(); // For instance...
}
}
UPDATE:
With regards to the piece of code you posted, you are throwing a pointer and catching by reference. The handler won't match. And since there is no other matching handler, std::terminate() will be called.
Instead, you should throw your exception by value:
throw Mage::Exception("failed to initialize OpenGL");
And if the code you posted is indeed the one you are using, you will see that control is transferred to your handler.
Based on the error message, you're using Visual Studio (2010) for your project. Unless you wrap your throw in a try/catch block, it will "sail through the roof" and be "handled" by the C++ runtime, which means calling abort(). You probably want something like this higher in the call stack:
try
{
SomeFunctionThatUltimatelyThrows();
}
catch(Exception & e)
{
// .. handle error - log, resume, exit, whatever
}
Note also Scott Meyers advice to always catch exceptions by reference. The "exception": If you're using MFC CExceptions though, you want to catch by pointer and call the Delete method for self-destructing heap-based exceptions.
Based on your edit, you may have a mismatch between throwing "by pointer" and catching "by reference". If you've resolved that and are still not getting your catch block to execute, you could try debugging the abort() call by using the CRT SetAbortHandler to install your own abort function. This could simply chain into the existing one, but would give an opportunity to set a breakpoint and examine the call stack to see what is going wrong.
C++ try-catch-throw logic for dummies. Note that this does NOT cover RAII / stack-based allocation / destruction.
When you throw an exception, an exception is said to be "propagating". It propagates up the call stack until it finds the first handler that can handle it (so it's caught) or until it's reached the root of your call stack.
If it is caught, execution continues from the point the exception is caught. The exception is destructed at the end of the catch block.
If it finds the root, it calls std::unhandled_exception, which usually calls std::terminate, which usually calls abort(). In short, everything's dropped ASAP.
If you throw an exception while an exception is currently propagating, you would have two propagating at a time. Java and C# have cutesy ways of dealing with this, but this should never happen in the first place - there's no exception handler that is logically going to handle combinations of exceptions. Do not throw exceptions while one is currently propagating. This rule isn't too hard to hold even if you don't use std::uncaught_exception() which you shouldn't.
While unwinding the stack / propagating the exception all objects found on the stack are destructed. These destructors should never throw an exception - after all, when destroying an object "fails", what else are you going to do after the destructor to fix it?
Always throw by value, catch by reference. If you throw & catch by pointer, you will most likely leak something, which is impossible by reference. If you catch by value, you will slice off your derived exception types. Catch by reference.
At the root of your software, include a catch-all - catch(...). This doesn't allow you to find out what exactly you've caught, but at least you can crash safely. Do this also when the called code may throw "something" that you don't know.
if I have a try catch block in my code, and the functions within the catch block generates an exception, what happens to that exception?
there's nothing special about throwing from a catch clause.
generally, if the catch clause is only used for some local cleanup then it's a good idea and good general programming practice to rethrow the current exception from the catch clause, and that's what the throw without argument is for.
throwing from a destructor, on the other hand, is generally problematic, because a destructor might be invoked automatically during stack unwinding (this then terminates the program).