views:

50

answers:

5

Let's say I have class that acts as a "smart pointer" and releases some kind of system resource when destroyed.

class Resource{
protected:
     ResourceHandle h;
public:
     Resource(ResourceHandle handle)
     :h(handle){
     }

     ~Resource(){
         if (h)
             releaseResourceHandle(h);//external function, probably from OS
     }
};

And I have some function that returns value used for initialization of "Resource":

ResourceHandle allocateHandle();

Now, if I do this in my code:

Resource resource(allocateHandle());

AND allocateHandle() throws an exception, what exactly will happen? Will the crash occur during construction of Resource() or before the construction?

Common sense tells me that because exception is thrown before allocateHandle returns, execution won't even enter Resource() constructor, but I'm not exactly sure about it. Is this a correct assumption?

+1  A: 

This is a correct assumption.

m1tk4
+3  A: 

Arguments are evaluated before any function call -- in this case the constructor --. Therefore, the exception is thrown before the constructor call

Scharron
A: 

Yes, your assumption is correct.

At this point you are only creating your parameters and pushing them on the stack. The Object of "Resource" is not even formed!

Therefore, an exception will not call the destructor during stack unwinding.

bits
+1  A: 

If the compiler entered the constructor, what value could it pass in from a function that didn't return?

DeadMG
+3  A: 

Yes you are correct (as everybody else has said).

But what you are alluding to (I think).
What happens to the object if the constructor was entered and the exception is thrown.

Would the destructor still get executed or not?

Destructors are only fired if the constructor actually finished (if an exception is throw that escapes the constructor then the constructor is not finished). In this case the constructor is not entered and thus the object does not exist and therefore the destructor will not be executed.

What happens if the exception is thrown while the constructor is executing.
In this case because the constructor was not completed the destructor will never be executed either, but what about all the member fields? If the constructor is left via an exception then all fully formed members will have their destructors called (A fully formed member is a member whose constructor has been called and completed successfully).

Martin York