Re: functions returning objects

From: James Dennett (jdennett_at_acm.org)
Date: 11/08/04


Date: Sun, 07 Nov 2004 19:41:52 -0800

Mark P wrote:

> Still more questions about the memory model in C++...
>
> Say I have a class C and a function which returns an object of type C:
>
> C f();
>
> Now somewhere along the line I call this function and want to store the
> result into another object of type C:
>
> // example 1
> C objC;
> objC = f();
>
> Am I correct in thinking that this first creates an object of type C as
> the result of f and then (assuming no other operator= has been defined)
> copies all of the members of that result into the members of objC?

In essence, yes. Actually, all classes *do* have a copy assignment
operator declared (either explicitly or implicitly), and if implicitly
declared it will be defined iff (a) it is used and (b) a synthesized
copy assignment operator which does memberwise assignment is valid.

The compiler should also check that C's copy constructor is accessible,
as returning an object by value involved (at least in principle) making
a copy. It happens that the compiler is allowed to skip making that
copy as an optimization, but it should still check that the code is
well-formed (including that the copy constructor is accessible). Note:
there is at least one compiler in circulation which omits that check,
and possibly more.

> (Side
> question: what happens if C is defined to have some const members?)

Then (b) above fails, and you'll get a diagnostic of some kind,
ideally telling you that you tried to use the implicitly declared
copy assignment operator of C, which could not be synthesized as
some members could not be assigned to.

> Could I use the default copy constructor and write:
>
> // example 2
> C objC(f());
>
> Again assuming that the copy constructor hasn't been explicitly defined,
> would this achieve the same results, namely the copying of all of the
> members of the result of f() into objC? Is this more efficient in that
> it doesn't first create a default C object as in example 1, or does it
> "behind the scenes" do the same thing?

Often it's more efficient. In this case, f() might, in some
circumstances, with some compilers, actually construct the object
directly in the space allocated for objC, and do no copying at all.

> Now what happens if I try something like:
>
> // example 3
> C &objCr = f();
>
> using a reference to C type?

Your compiler should report an error, cannot bind temporary f() to
non-const reference objCr. (MSVC++ is pretty bad at this.)

> Is this more efficient because it avoids
> copying those member parameters, or is this now a reference to an object
> that doesn't exist.

Neither, but if you do

C const& objCRC(f());

then the return value of f() *still* might or might not be copied.

> I've read of the perils of returning references to locally created
> objects-- not sure if that applies in this case however.

It would, except for a special rule saying that the lifetime of the
temporary object "bound" to objCRC above is extended to match the
scope of objCRC, if objCRC is a local variable (and there are other
rules for if it's a member variable, best avoided).

> My intuition
> is that this is ok, because the return value of f is an object and not a
> reference, but where exactly "is" the return value of f() in terms of
> scopes and stack frames?

The return value of f() is an object. Returning objects means copying
them, unless the compiler optimizes the copy away (but nothing about
optimizing that copy away allows it to change the lifetime of the
returned value).

-- James



Relevant Pages

  • Re: STL compile error
    ... In article, John ... > No but its bad style, because if you later add data members to your class, ... > you then have to remember to update the copy constructors and assignment ... With the compiler generated versions this is done autmatically, ...
    (comp.lang.cpp)
  • Re: struct alignment
    ... necessary so that all the members can be accesssed correctly. ... Does any compiler let you do this? ... Permit reordering of struct members, ... but that surely is rare. ...
    (comp.lang.c)
  • Re: File conversion
    ... the appropriate changes to both record layouts, ... You would then have to do a detailed comparison of what fields the compiler found to correspond. ... Once you have done that, and proven that your COPY members are defined correctly, you're home free! ... future changes to the COPY members could blow you right out of the water.... ...
    (comp.lang.cobol)
  • Re: Home based Internet research Jobs
    ... We are now hiring home based workers to complete simple online research ... PAY) they are not gonna pay you after you complete your assignment!! ... it is true they pay some of the members.. ...
    (comp.os.vms)
  • Re: Please help optimize (and standarize) this code...
    ... If you want to be sure that this also works with a C99 compiler you ... This obviously assumes that the members of the NameExt structure are ... itoa() isn't a standard C function, so this will fail on systems ...
    (comp.lang.c)