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).


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).


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.


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