badri
badri

Reputation: 627

Why do programmers use both std::bad_alloc and std::exception. Is std::exception alone not sufficient

Consider the following code snippet

try {
    goesWrong();
}
catch (const std::bad_alloc &e)
{
    std::cout << "Catching bad_alloc: " << e.what() << std::endl;
}
catch (const std::exception &e)
{
    std::cout << "Catching exception: " << e.what() << std::endl;
}

Why do we need to catch a lot of individual exceptions. Just std::exception at the end is enough to catch all exceptions isn't it ? Why an extra 4 lines of code to catch std::bad_alloc explicitly when std::exception is going to catch it anyway?

Upvotes: 0

Views: 168

Answers (4)

Alan Birtles
Alan Birtles

Reputation: 36479

The separate catch statements are so that you have have different behaviour depending on the type of exception thrown.

For example you might be expecting a bad_alloc and can recover from it by trying again with a smaller allocation or by freeing memory elsewhere.

Just std::exception at the end is enough to catch all exceptions isn't it ?

No, catching std::exception is enough to catch all thrown exceptions which are derived from std::exception. In c++ std::exception doesn't have any special meaning, you can throw any type as an exception. It is recommended to derive from std::exception but not required.

There are even pitfalls like if you have multiple inheritance and your exception class derives from std::exception twice it won't be caught.

To catch all exceptions you need to catch ...:

struct my_exception {};

try
{
  switch ( i )
  {
  case 1:
    throw std::runtime_error( "i is 1" );
  case 2:
    // bad idea, who is responsible for freeing the exception? But perfectly legal
    throw new std::runtime_error( "i is 1" );
  case 3:
    // you can throw numbers too
    throw i;
  case 4:
    throw my_exception();
  }
}
catch ( const std::exception& )
{
}
catch ( const my_exception& )
{
}
catch ( ... )
{
}

Upvotes: 2

Aconcagua
Aconcagua

Reputation: 25536

More an addition to the answers given so far than a separate, own one:

Actually, you could base exception handling on evaluation of the what() string:

catch(std::exception const& e)
{
    if(strcmp(e.what(), "some text"))
    {
        doThis();
    }
    else if(strstr(e.what(), "something"))
    {
        doThat();
    }
    // ...
}

However, this requires that you know the exact string contents. What, if these differ across different C++ implementations? What, if these are localised on some systems? Do you really want to cope with all such matters? Additionally, text processing is much more expensive than just catching different exceptions.

So with different exceptions, you gain portability, safety (consider typos in the strings you compare with...), easier and better readable code and, as a bonus, efficiency.

Upvotes: 1

eerorika
eerorika

Reputation: 238401

Why do we need to catch a lot of individual exceptions.

In general, because that allows different behaviour depending on the type of the caught exception.

In this case, there's need to do so, since this possibility is not taken advantage of.

Consider for example a case where you have allocated a large cache in memory. In that case, when catching std::bad_alloc, you might release the cache and try again, while that approach would not be useful in the case of other exceptions.

Upvotes: 3

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 122830

exception could be any expception while bad_alloc is more specific. Not only you might want to react differently for different kind of exceptions, but also it more clearly expresses what is going on. After all code is written to express your intention not just to make it work somehow.

Upvotes: 2

Related Questions