Copy constructor not being called on function return

John (Eljay) Love-Jensen eljay@adobe.com
Tue Nov 4 12:35:00 GMT 2008


Hi Stuart,

> Can anyone think of a more elegant way of managing this, and is there a way of determining at compile-time whether a compiler supports NRVO?

I realize your example is simplified to illustrate the problem, so my answer that follows is not generally applicable.  But I hope the gist of the concept is evident.

I'd write someFunc this way:

std::vector<char> someFunc()
{
  std::vector<char> some_data(100);
  return some_data;
}

That way you don't get into the situation of having NVRO messing up your memory ownership.  The smart pointer -- in this case, the vector -- owns the array memory.

The situation you present is a smart pointer with muddled ownership, and uses a side-effect in the copy-constructor to... umm (I don't have a word for it)... "finalize" the memory ownership.  (Yes, what you are doing is a side-effect, because if the SUBROUTINE's constructor is built in-place where the CALLER'S SmartPtr is located, thus eliding the unnecessary copy-constructor -- i.e., NVRO -- which makes a bug in how you've got it plumbed up.)

Alternatively, trying to keep your SmartPtr mostly as is, I'd have it used this way by adding another method:

SmartPtr someFunc()
{
  char some_data[100];
  SmartPtr smart_ptr;
  smart_ptr.setConst(some_data, sizeof some_data);
  //...
  smart_ptr.finalize(); // makes its own copy instead of borrowed "ownership".
  return smart_ptr;
}

The downside is remembering to call that routine which makes its own allocation which the SmartPtr then really owns and manages.

Sincerely,
--Eljay



More information about the Gcc-help mailing list