Topic: Are return values copied?


Author: jimad@microsoft.com (Jim Adcock)
Date: 23 Sep 93 19:55:11 GMT
Raw View
In article <1993Sep17.172353.19199@vedge.com| hendrik@vedge.com (Hendrik Boom) writes:
|ARM, page 288, section12.6.1 says
| The initialization that occurs in argument passing and function
| return is equivalent to the form
|

Same page has an example making it clear that:

 T x = a;

is identically equivalent to:

 T x(T(a));

IE first a is converted to type T, then a copy constructor is used
to initialize x;  However, (T(a)) forms an unnamed temporary subject
to "The fundamental rule" on page 299 12.1c stating that temps can
be optimized out if the only way that the user can detect their
presence or elimination is via side-effects of ctors and dtors.

Thus, it would seem this form does not necessarily require a copy
constructor.  (T(a)) could be constructed in-place at the location
of object x, eliminating the need to copy ctor the temp from (T(a))
to x.  Assuming the necessary ctors to do this are available and
accessable, of course.

In summary then, the implication is that C++ *does not* necessarily
return-by-copy, but rather returns-by-value.  This would make the
rule for returns in C++ the same as in C, again, return-by-value,
not return-by-copy.  Here's a simple example:

T f()
{
 T a;
 return a;
}

void g()
{
 f();
}

Does the return of 'a' necessitate a copy?  I'd claim obviously not.
There is no need for any such copy, why should a compiler have to
introduce an unnamed temporary to hold such a copy of the returned
value, call a copy ctor to make that temporary, when it is trivially
obvious that the value is never used?





Author: prange@cs.tu-berlin.de (Martin Prange)
Date: 17 Sep 1993 10:36:44 GMT
Raw View
In article <747744090snz@avondale.demon.co.uk> jfhall@avondale.demon.co.uk (John Hall) writes:

[deleted]

>
> >In article <1993Sep7.203951.3465@is.morgan.com> jlieb@is.morgan.com (Jerry
> > Liebelson) writes:
> >>
> >>       X f()
> >>       {
> >>               X a;
> >>               return a;
> >>       }
> >>
> >>   I do not see the copy constructor X(X&) being called to copy the
> >>   object a to the return value. (We are using the CenterLine compiler.)
> >>   MY QUESTION IS, is it implementation dependent as to whether such a
> >>   copy is actually performed?
> >
> >The answer is that that's a good question.
> >
> >If anyone can provide a citation to support the contention that a copy
> >constructor MUST be called in this case, please do.
>

Using the Centerline-compiler at SEL-ALCATEL BERLIN,
I must agree that a function with an Object as a return value,
which will introduce the copying of a tepporary for example,
will be translated to a function with an additional parameter
reference of the return type, and when calling this function,
the compiler will create a local variable of the return type,
thus reducing the copying.


e.g.: ( bad on for SW-eng! ;) )

 String Concat(const String&, const String&);

 calling:
  String s1,s2;
  String s= Concat(s1,s2);


----->
 Concat(const String&, const String&,String&);

 calling:
  String s1,s2;
 -->     String _tmp_X42;
  String s(s1,s2,_tmp_X42);


P.S: centerline needs 48 MB RAM , do you fit these requrement? (sigh)


    ;) Martin Prange (prange@cs.tu-berlin.de)







Author: iwan@host03.turing.ac.uk (Iwan Eising)
Date: Fri, 17 Sep 1993 18:18:17 GMT
Raw View
In article <747744090snz@avondale.demon.co.uk>, jfhall@avondale.demon.co.uk (John Hall) writes:
|> In article <rfgCD5IvC.6zG@netcom.com> rfg@netcom.com writes:
|>
|> >In article <1993Sep7.203951.3465@is.morgan.com> jlieb@is.morgan.com (Jerry
|> > Liebelson) writes:
|> >>
|> >>       X f()
|> >>       {
|> >>               X a;
|> >>               return a;
|> >>       }
|> >>
|> >>   I do not see the copy constructor X(X&) being called to copy the
|> >>   object a to the return value. (We are using the CenterLine compiler.)
|> >>   MY QUESTION IS, is it implementation dependent as to whether such a
|> >>   copy is actually performed?
|> >
|> >The answer is that that's a good question.
|> >
|> >If anyone can provide a citation to support the contention that a copy
|> >constructor MUST be called in this case, please do.
|>
|> ARM 6.6.3:
|> A return statement with an expression ....  If required, the expression is
|> converted, as an initialisation, to the return type of the function in which
|> it appears.  This may involve the construction and copy of a temporary object
|> (12.2).
|>
|> ARM 12.2:
|> In some circumstances it may be necessary or convenient for the compiler to
|> generate a temporary object.  Such introduction of temporaries is
|> implementation dependent.
|>
|> *if required*  *may involve*   *implemention dependent*   And "a" is already
|> the right type.
|>
|> There doesn't seem to be any "MUST" about it.

Why not make sure that a copy is returned and do it yourself ? So you can mess with the returned value as much as you like, without wrecking the whole system.

Iwan




Author: hendrik@vedge.com (Hendrik Boom)
Date: Fri, 17 Sep 1993 17:23:53 GMT
Raw View
rfg@netcom.com (Ronald F. Guilmette) writes:
: In article <1993Sep7.203951.3465@is.morgan.com> jlieb@is.morgan.com (Jerry Liebelson) writes:
: > Hi,
: >   Given some class X and function f:
: >
: > X f()
: > {
: >  X a;
: >  return a;
: > }
: >
: >   I do not see the copy constructor X(X&) being called to copy the
: >   object a to the return value. (We are using the CenterLine compiler.)
: >   MY QUESTION IS, is it implementation dependent as to whether such a
: >   copy is actually performed?
:
: The answer is that that's a good question.
:
: If anyone can provide a citation to support the contention that a copy
: constructor MUST be called in this case, please do.

ARM, page 288, section12.6.1 says
 The initialization that occurs in argument passing and function
 return is equivalent to the form

  T x = a;

Does this form require a copy constructor?

: --
:
: -- Ronald F. Guilmette ------------------------------------------------------
: ------ domain address: rfg@netcom.com ---------------------------------------
: ------ uucp address: ...!uunet!netcom.com!rfg -------------------------------
--
-------------------------------------------------------
Try one or more of the following addresses to reply.
at work: hendrik@vedge.com,  iros1!vedge!hendrik
at home: uunet!ozrout!topoi!hendrik




Author: kanze@us-es.sel.de (James Kanze)
Date: 20 Sep 93 19:48:46
Raw View
In article <1993Sep17.172353.19199@vedge.com> hendrik@vedge.com
(Hendrik Boom) writes:

|> rfg@netcom.com (Ronald F. Guilmette) writes:
|> : In article <1993Sep7.203951.3465@is.morgan.com> jlieb@is.morgan.com (Jerry Liebelson) writes:
|> : > Hi,
|> : >   Given some class X and function f:

|> : > X f()
|> : > {
|> : >  X a;
|> : >  return a;
|> : > }

|> : >   I do not see the copy constructor X(X&) being called to copy the
|> : >   object a to the return value. (We are using the CenterLine compiler.)
|> : >   MY QUESTION IS, is it implementation dependent as to whether such a
|> : >   copy is actually performed?

|> : The answer is that that's a good question.

|> : If anyone can provide a citation to support the contention that a copy
|> : constructor MUST be called in this case, please do.

|> ARM, page 288, section12.6.1 says
|>  The initialization that occurs in argument passing and function
|>  return is equivalent to the form

|>   T x = a;

|> Does this form require a copy constructor?

According to the ARM (section 12.6.1): "...a single value is pecified
as the initializer uning the = operator.  This value is used as the
argument to a copy constructor.  Typically, that call of the copy
constructor can be eliminated."

Traditionally, this has been interpreted to mean that the copy
constructor must be accessible, but need not be called.  This
interpretation is in fact made explicite in the comments following the
above quote.
--
James Kanze                             email: kanze@us-es.sel.de
GABI Software, Sarl., 8 rue du Faisan, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                   -- Beratung in industrieller Datenverarbeitung




Author: jfhall@avondale.demon.co.uk (John Hall)
Date: Sat, 11 Sep 1993 10:41:30 +0000
Raw View
In article <rfgCD5IvC.6zG@netcom.com> rfg@netcom.com writes:

>In article <1993Sep7.203951.3465@is.morgan.com> jlieb@is.morgan.com (Jerry
> Liebelson) writes:
>>
>>       X f()
>>       {
>>               X a;
>>               return a;
>>       }
>>
>>   I do not see the copy constructor X(X&) being called to copy the
>>   object a to the return value. (We are using the CenterLine compiler.)
>>   MY QUESTION IS, is it implementation dependent as to whether such a
>>   copy is actually performed?
>
>The answer is that that's a good question.
>
>If anyone can provide a citation to support the contention that a copy
>constructor MUST be called in this case, please do.

ARM 6.6.3:
A return statement with an expression ....  If required, the expression is
converted, as an initialisation, to the return type of the function in which
it appears.  This may involve the construction and copy of a temporary object
(12.2).

ARM 12.2:
In some circumstances it may be necessary or convenient for the compiler to
generate a temporary object.  Such introduction of temporaries is
implementation dependent.

*if required*  *may involve*   *implemention dependent*   And "a" is already
the right type.

There doesn't seem to be any "MUST" about it.

--
John Hall     jfhall@avondale.demon.co.uk    CompuServe: 100016,1210




Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Fri, 10 Sep 1993 18:47:36 GMT
Raw View
In article <1993Sep7.203951.3465@is.morgan.com> jlieb@is.morgan.com (Jerry Liebelson) writes:
> Hi,
>   Given some class X and function f:
>
> X f()
> {
>  X a;
>  return a;
> }
>
>   I do not see the copy constructor X(X&) being called to copy the
>   object a to the return value. (We are using the CenterLine compiler.)
>   MY QUESTION IS, is it implementation dependent as to whether such a
>   copy is actually performed?

The answer is that that's a good question.

If anyone can provide a citation to support the contention that a copy
constructor MUST be called in this case, please do.

--

-- Ronald F. Guilmette ------------------------------------------------------
------ domain address: rfg@netcom.com ---------------------------------------
------ uucp address: ...!uunet!netcom.com!rfg -------------------------------




Author: davisonj@bnr.ca (John M Davison)
Date: 10 Sep 1993 22:23:33 GMT
Raw View
        In article <rfgCD5IvC.6zG@netcom.com> rfg@netcom.com (Ronald F.
Guilmette) writes:
>The answer is that that's a good question.
>
>If anyone can provide a citation to support the contention that a copy
>constructor MUST be called in this case, please do.

        Depends on whether or not the copy constructors has potential
side-effects, right?

        From what I remember reading in a Stroustrup paper (possibly outdated),
Stroustrup talks about a case like this, and he effectively says that a good
compiler should be able to optimize this out.

        (Unfortunately, the compiler may not have enough information at that
time to know if side effects occur or not -- for example, if the comstructor
calls an undefined function that gets pulled in at link time.)

        Me?  I would prefer the way C+@ does it -- using a implicit named
return parameter ("r") with its own scope.  Introducing this in C++, perhaps as
a specially named variable with its own distinct namespace, would solve a lot
of problems, but it would probably introduce a lot of new ones, and we'd still
have to support the old C-style return semantics anyway.
--
+--------+
|John    |      "Who says MS-DOS isn't multitasking? You
|Davison |       just need one box per task!"
+--------+                              -- Mike Meyer, mwmeyer@ingres.com