Can a function return statement be elided?

M

Michael Klatt

I have a resource handle class (call it ResourceHandle) that works
like std::auto_ptr to automatically manage resource pointers from a C
API (call them T*):

class ResourceHandle
{
public :
ResourceHandle(T* ptr) { /* take ownership of T* */ }
~ResourceHandle() { /* release T* resource */ }
};

ResourceHandle f() { /* return a new T* */ }

Function f() relies on ResourceHandle(T*) being called as a result of
the return statement to avoid a resource leak. But what happens if
the return value of f() is not used in the calling function?

int main()
{
ResourceHandle resource(f()); // no leak
f(); // resource leak if return statement is elided?
}
 
A

Andrew Koenig

class ResourceHandle
{
public :
ResourceHandle(T* ptr) { /* take ownership of T* */ }
~ResourceHandle() { /* release T* resource */ }
};

ResourceHandle f() { /* return a new T* */ }

Function f() relies on ResourceHandle(T*) being called as a result of
the return statement to avoid a resource leak. But what happens if
the return value of f() is not used in the calling function?

int main()
{
ResourceHandle resource(f()); // no leak
f(); // resource leak if return statement is elided?
}

Even if the result of evaluating f() is not used in any other way, it will
still be destroyed.

However, your program may have a serious problem. Your class ResourceHandle
does not have a copy constructor, which means that when you copy a
ResourceHandle object, doing so implicitly copies its members. Now consider
this:

ResourceHandle f()
{
ResourceHandle res;

// Do something here that gives a value to result

return res;
}

When f exits, res will be copied to serve as the return value and then
destroyed. Whatever resource res refers to will presumably be freed. Now,
on the caller's side:

f();

f returns a result that is put in a compiler-generated temporary and then
destroyed. That result is a copy of the local variable named in function f.
When the result is destroyed, the resource to which it refers is
freed--presumably for the second time.

I suspect that behavior is not what you have in mind.
 
M

Michael Klatt

Andrew Koenig said:
Even if the result of evaluating f() is not used in any other way, it will
still be destroyed.

However, your program may have a serious problem. Your class ResourceHandle
does not have a copy constructor, which means that when you copy a
ResourceHandle object, doing so implicitly copies its members. Now consider
this:

I just posted sample code to help illustrate my question. The real
version of ResourceHandle is implemented like std::auto_ptr. If I use
an auto_ptr example I think my question will be more clear.

auto_ptr<T> f()
{
return new T;
}

Will the auto_ptr constructor be called in this case if the return
value is ignored? Or is it safer to write the function like this to
ensure that the return value gets constructed (and thus destructed):

auto_ptr<T> f()
{
return auto_ptr<T>(new T);
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,023
Latest member
websitedesig25

Latest Threads

Top