Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between std::exception and "..."

Tags:

c++

exception

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.

like image 730
hong pei Avatar asked Jul 01 '13 15:07

hong pei


People also ask

What does STD exception mean?

std::exceptionProvides consistent interface to handle errors through the throw expression. All exceptions generated by the standard library inherit from std::exception.

What is Runtime_error in exception handling?

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.

What are the various C++ standard exceptions?

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.


2 Answers

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 exceptions 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-throws 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.

like image 124
John Dibling Avatar answered Oct 16 '22 08:10

John Dibling


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
like image 21
jerry Avatar answered Oct 16 '22 09:10

jerry