A: catch(...)
B: catch(std::exception& e)
the question is what can A catch but B cannot.
And why in C++ an universal root exception that can catch anything is not introduced
--- added I am sorry, I should have said that I understand in C++ you can thrown any type like int, but apart from this, what else can be thrown?
My problem is that I am trying to find what exception is thrown from code, which can be caught by A but not B. This exception is definitely not a type like "int". It must be a system exception or memory violation sort of thing. I am just wondering what that could be.
std::exceptionProvides consistent interface to handle errors through the throw expression. All exceptions generated by the standard library inherit from std::exception.
std::runtime_errorDefines a type of object to be thrown as exception. It reports errors that are due to events beyond the scope of the program and can not be easily predicted.
C++ exception handling is built upon three keywords: try, catch, and throw. throw − A program throws an exception when a problem shows up. This is done using a throw keyword. catch − A program catches an exception with an exception handler at the place in a program where you want to handle the problem.
catch (...)
is a so-called "catch all" block. It will catch any C++ exception.
catch(std::exception& e)
will catch only exceptions that are derived from std::exception
.
Here is an example of an exception that will be called by the catch-all, but not the second version:
throw 42;
This might seem odd to you, and it is. The important thing to realize is that anything can be thrown as a C++ exception -- not just exception
s or things derived from exception
. As @bames53 mentions in the comments, there is no root exception type that all exceptions are derived from, like there is in some other languages.
It is also important to note that a catch-all block is very easy to abuse. In fact, as a general rule of thumb it might be best to assume that all catch-all blocks are program defects. Of course, there is no "always" in programming, but this is a safe assumption to start with when you are learning to use exceptions.
The reason why catch-all blocks are Evil is because of how they are typically used. Normally, a naive programmer will write a catch-all in an attempt to catch any programming error and then, critically, continue letting the program has run as if nothing has happened. This is a disaster waiting to happen. The program state is now indeterminate. Something, somewhere has gone wrong. You cannot safely ignore exceptions and keep going like everything is just fine. Even if your program does continue to run, there might be a subtle heap corruption somewhere that will adulterate the program's computations or its outputs. When heap corruptions do occur, the best thing that you as the programmer can hope for is an immediate crash. That way you can get a call stack and a dump file at the point of corruption and find and fix the problem. But when you have a catch-all in place, you have lost all the context where this corruption takes place. It becomes nearly impossible to find the real defect in your code.
Of course, there are valid and valuable uses of a catch all handler. One on the most common is to write a global exception handler which then re-throw
s the exception. This global handler could initiate some kind of fault logging, perhaps by either logging an error itself, or spawning an external program which does the logging outside of the failing program. By re-throwing the exception, you give delegates an opportunity to handle the exceptions that can be handled, while allowing the exception which can't be handled to terminate the program.
Rethrowing an exception is simple to do. Simply call throw
with no argument, as with:
catch (...)
{
// some magic
throw;
}
Another thing to keep in mind is that when you do catch an exception, it is generally best to catch a const
reference, rather than just a reference.
The short answer is anything without std::exception
in its (public) inheritance heirarchy:
#include <exception>
#include <iostream>
int main()
{
try
{
throw false;
}
catch(std::exception& e)
{
std::cout << "Caught std::exception" << std::endl;
}
catch(...)
{
std::cout << "Caught something else" << std::endl;
}
return 0;
}
Output:
Caught something else
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With