Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ object as return value: copy or reference?

I wanted to test how C++ behaves when the return value of a function is an object. I made this little example to watch how many bytes are allocated and determine whether the compiler makes a copy of object (like when object is passed as a parameter) or instead returns some kind of reference.

However, I couldn't run this very simple program and I have no idea why. Error says: "Debug assertion failed! Expression: BLOCK_TYPE_IS_INVALID" in some dbgdel.cpp file. Project is a win32 console application. But I'm pretty sure that there is something wrong with this code.

class Ctest1
{
public:
   Ctest1(void);
   ~Ctest1(void);

   char* classSpace;
};

Ctest1::Ctest1(void)
{
   classSpace = new char[100];
}

Ctest1::~Ctest1(void)
{
   delete [] classSpace;
}

Ctest1 Function(Ctest1* cPtr){
   return *cPtr;    
}

int _tmain(int argc, _TCHAR* argv[])
{
   Ctest1* cPtr;

   cPtr=new Ctest1();


   for(int i=1;i<10;i++)
      *cPtr = Function(cPtr);


   delete cPtr;

   return 0;
   }
like image 613
user1316208 Avatar asked Apr 05 '12 20:04

user1316208


People also ask

Does C return a copy?

By the technical, literal interpretation of the question, the answer is no. C functions have exactly one return type (which might be void ), and return at most one value.

Can you return by reference in C?

Master C and Embedded C Programming- Learn as you go So it is not legal to return a reference to local var. But you can always return a reference on a static variable.

Does returning an object copy it C++?

commercial-grade C++ compilers won't do that: the return statement will directly construct x itself. Not a copy of x, not a pointer to x, not a reference to x, but x itself.

Does return by value call copy constructor?

In C++, a Copy Constructor may be called for the following cases: 1) When an object of the class is returned by value. 2) When an object of the class is passed (to a function) by value as an argument. 3) When an object is constructed based on another object of the same class.


1 Answers

Getting (finally) to what you originally intended to ask about, the short answer is that it's rarely a problem. The standard contains a clause that specifically exempts a compiler from having to actually use the copy constructor on a return value, even if the copy constructor has side effects, so the difference is externally visible.

Depending on whether you're returning a variable, or just a value, this is called either named return value optimization (NRVO) or just return value optimization (RVO). Most reasonably modern compilers implement both (some, such as g++ even do it when you turn off optimization).

To avoid copying the return value, what the compiler does is pass the address where the copy would go as a hidden parameter to the function. The function then constructs its return value in that place, so after the function returns, the value is already there without being copied.

This is common enough, and works well enough that Dave Abrahams (at the time a C++ standard committee member) wrote an article some years ago showing that with modern compilers, people's attempts at avoiding the extra copying often actually produce code that's slower than if you just write simple, obvious code.

like image 178
Jerry Coffin Avatar answered Oct 05 '22 10:10

Jerry Coffin