Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception catching mechanism, C++

Consider this code:

int main()
{
    try 
    {
        throw std::range_error("");
    }
    catch (std::bad_alloc) 
    {
        std::cout << "AAAA" << std::endl;
        throw;
    }
    catch (std::range_error) 
    {
        std::cout << "BBB" << std::endl;
        throw;
    }
    catch (std::exception)
    {
        std::cout << "CCC" << std::endl;
    }
    std::cout << "DDD" << std::endl;
}

Here I throw an exception of type std::range_error and trying to catch it.
Logically the first catch block cannot catch it because of type mismatch(std::bad_alloc and std::range_error).
The second catch block must catch it because they are the same types of std::range_error.
And also, when I rethrow the exception in second catch block it must be caught in the third catch block.

So my output must be

BBB
CCC
DDD

But I only get the BBB output with the termination.

Can anybody please explain me the behavior??

like image 813
Eduard Rostomyan Avatar asked Sep 11 '16 18:09

Eduard Rostomyan


People also ask

What is the mechanism of exception handling?

Exception handling is a mechanism that separates code that detects and handles exceptional circumstances from the rest of your program. Note that an exceptional circumstance is not necessarily an error. When a function detects an exceptional situation, you represent this with an object.

How is an exception handled in C?

The C programming language does not support exception handling nor error handling. It is an additional feature offered by C. In spite of the absence of this feature, there are certain ways to implement error handling in C. Generally, in case of an error, most of the functions either return a null value or -1.

What is catching an exception?

When an appropriate handler is found, the runtime system passes the exception to the handler. An exception handler is considered appropriate if the type of the exception object thrown matches the type that can be handled by the handler. The exception handler chosen is said to catch the exception.


2 Answers

When you re-throw an exception, you are throwing it completely out of the context of the current exception handling block.... So,

try 
{
    throw std::range_error("");
}
catch (std::bad_alloc) 
{
    std::cout << "AAAA" << std::endl;
    throw;
}
catch (std::range_error) 
{
    std::cout << "BBB" << std::endl;
    throw;
}
catch (std::exception)
{
    std::cout << "CCC" << std::endl;
}

is one exception handling block. Therefore, on meeting the first throw in any of the catch blocks, it leaves the whole block to look for another handling block (try-catch) outside the current scope. if not found, the program terminates.

Please see try-catch block in C++

To print as you initially thought ... Live On Coliru ...

int main()
{
    try{
        try{
            try{
                throw std::range_error("");
            }
            catch (std::bad_alloc) {
                std::cout << "AAAA" << std::endl;
                throw;
            }
        }
        catch (std::range_error) {
            std::cout << "BBB" << std::endl;
            throw;
        }
    }
    catch (std::exception){
        std::cout << "CCC" << std::endl;
    }
    std::cout << "DDD" << std::endl;
}

Prints:

BBB
CCC
DDD

For the record: please avoid using exceptions for control flow that could be done with simple if-else ladder in production code

like image 177
WhiZTiM Avatar answered Sep 27 '22 19:09

WhiZTiM


To re-catch the range_error and new outer try catch block is required.

#include <iostream>

int main()
{
  //outer try catch ------------------------
  try { 

    // inner try catch ---------------------
    try 
    {
      throw std::range_error("");
    }
    catch (std::bad_alloc) 
    {
      std::cout << "AAAA" << std::endl;
      throw;
    }
    catch (std::range_error) 
    {
      std::cout << "BBB" << std::endl;
      throw;
    }
    // -------------------------------
  }

  catch (std::exception)
  {
    std::cout << "CCC" << std::endl;
  }
  // --------------------------------

  std::cout << "DDD" << std::endl;
}

Output

BBB
CCC
DDD
like image 25
robor Avatar answered Sep 27 '22 18:09

robor