Home > other >  How I can determine the "nearest" exception handler
How I can determine the "nearest" exception handler

Time:03-25

From [except.throw]/2:

When an exception is thrown, control is transferred to the nearest handler with a matching type ([except.handle]); “nearest” means the handler for which the compound-statement or ctor-initializer following the try keyword was most recently entered by the thread of control and not yet exited.

First of all, I really can't understand this quote properly, and how it is applied in a particular code. So any understandable explanations, with simple words, will be very appreciated.

Consider this two code snippets:

/ * code A */

try
{
  throw 1;
}
catch (int) // nearest handler for throwing 1. #first_handler
{
}

-----------------------------------------------

/* code B */

try
{
  try
  {
    throw 1;
  }
  catch (int) // nearest handler for throwing 1. #second_handler
  {
    throw 2;
  }
}
catch (int) // nearest handler for throwing 2
{
} 

Because I cannot understand the above quote, I don't know how I can determine the nearest handler, and I cannot apply [except.throw]/2 in the above examples. My question is just how does [except.throw]/2 is applied in the above code? or in other words, why first_handler and second_handlerare nearest handlers?

CodePudding user response:

Exceptions travel upwards, hence you can look for the next try then see if it has a matching catch, if not continue. For example

try {                                  // 4
    try {                              // 2
        throw "foo";                   // 1
    } catch(int) { }                   // 3
} catch(...) {                         // 5
    std::cout << "hello exception";
}

When the excpetion is thrown in 1 then control flow goes backwards and the first try is the one in 2. It does not have a matching catch, it only catches int (3). Hence, you look further upwards to find the try in 4. It has a catch that catches any exception 5 and that is the "nearest".


[...] "“nearest” means the handler for which the compound-statement following the try keyword was most recently entered by the thread of control and not yet exited." What that's "not yet exited"? I can't get the bold part.

Thats the second example:

try            // try 2
{
  try          // try 1
  {
    throw 1;
  }            // <---- the try block is exited here
  catch (int)  // catch 1
  {
    throw 2;
  }
}
catch (int)    // catch 2
{
} 

throw 2 will be handled by catch 2 because thats the nearest handler. The nearest handler is not catch 1 because that belongs to try 1. And when throw 2 is executed then the try 1 block is already exited.

  • Related