Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using `throw;` on a modified exception

I have a function foo that can throw a bar exception.

In another function I call foo but I have the ability to add some more detail to the bar exception if thrown. (I'd rather not pass such information as a parameter to foo as it doesn't really belong there due to the generic nature of that function.)

So I do this in the caller:

try {
    foo();
} catch (bar& ex){
    ex.addSomeMoreInformation(...);
    throw;
}

Will throw re-throw the modified exception or do I need to use throw ex;? The latter would presumably take a value copy so I'd rather not do that. Would throw take a value copy too? I suspect it wouldn't.

(I'm aware I could verify but I'm concerned about stumbling on an unspecified or undefined construct so would like to know for sure).

like image 890
P45 Imminent Avatar asked Nov 12 '14 09:11

P45 Imminent


3 Answers

Actually, the standard is very precise here. [except.handle]/17:

When the handler declares a reference to a non-constant object, any changes to the referenced object are changes to the temporary object initialized when the throw-expression was executed and will have effect should that object be rethrown.

And [except.throw]/8:

A throw-expression with no operand rethrows the currently handled exception (15.3).

like image 64
Columbo Avatar answered Nov 08 '22 09:11

Columbo


C++11 §15.1/8:

A throw-expression with no operand rethrows the currently handled exception (15.3). The exception is reactivated with the existing temporary; no new temporary exception object is created.

like image 26
Cheers and hth. - Alf Avatar answered Nov 08 '22 09:11

Cheers and hth. - Alf


In this case you should use throw to get the desired behavior...i.e throw would throw the modified exception as the exception was caught by reference.

Let me try to make difference between these throw explicit through examples:-

class exception
{
};

class MyException : public exception
{
};

void func()
{
  try
  {
    throw MyException();
  }
  catch( exception& e )
  {
    //do some modification.
    throw;                    //Statement_1
    throw e;                  //Statement_2
   }
}

Statment_1:-

What throw does is it just re-throws what the current exception is i.e it doesn't make further copies ( as was made when exception was thrown initially). So if you make any changes to the caught exception here...it would also be there in the caller routine.

Statement_2:-

This is throwing the "exception" which was originally caught as MyException i.e it would make the copy again. So, just forget about changes you made it won't even passes or*ginal exception to the caller. It throws "exception" to the caller routine.

Hope I am clear ( and RIGHT ON TRACK OF C++ STANDARD )enough...

like image 3
ravi Avatar answered Nov 08 '22 09:11

ravi