views:

59

answers:

3

Lets consider I have the following function:

SomeType createSomeType();

which can throw depending on some reasons.

Then:

SomeType val = SomeType(); // initial value

try
{
  val = createSomeType(); // here
}
catch (std::exception&)
{
}

If createSomeType() throws, can I always assume that val value is unchanged ?

+7  A: 

Yes, if createSomeType() throws an exception, the assignment will not happen. The flow of control will go from the throw statement, through the destructors of any objects createSomeType() has on the stack and finally to the catch statement.

Ferruccio
+1  A: 

If the assignment operator for SomeType is exception-safe then you can be sure that either val will be assigned a consistent new value or its initial value will remain unchanged.

However the exception might be thrown by either createSomeType() or by the assignment after createSomeType() runs successfully. If the assignment operator for SomeType is overloaded and it can throw exceptions it might happen that val ends up in "half-assigned" inconsistent state. The latter is a result of not adopting exception safety in SomeType design which is bad but still can happen.

sharptooth
If `createSomeType` throws, will the body of the assignment operator ever be entered? How could it change the value in that case?
Space_C0wb0y
@Space_C0wb0y: It might happen that the body doesn't throw, but the overloaded assignment throws.
sharptooth
The OP explicitly asks for the case when `createSomeType` throws, so the assignment operator does not play a role (in that specific scenario).
Space_C0wb0y
@sharptooth OP said "createSomeType() throws"
PigBen
@PigBen: Okay, I edited the answer to put the emphasis right.
sharptooth
Even though the OP says that createSomeType is the method which may throw an exception, this is still a very useful answer. It is good to point out that it is possible that the assignment operator could throw. That is a (I hope) rare case, so it wouldn't be something that I would normally think about.
A. Levy
A: 

From Standard docs 15.2.1,

As control passes from a throw-expression to a handler, destructors are invoked for all automatic objects constructed since the try block was entered. The automatic objects are destroyed in the reverse order of the completion of their construction.

Hence the val value, will not change...

liaK