From -5224371893867980253
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f78e5,f5d433881cc29cff
X-Google-Attributes: gidf78e5,public
From: Jason Merrill <jason@cygnus.com>
Subject: Re: Named return value optimisation- reprise.
Date: 1997/06/20
Message-ID: <u9zpsmuktq.fsf@yorick.cygnus.com>#1/1
X-Deja-AN: 251381863
References: <33a345bf.7425526@news.ipswich.gil.com.au> <33A478C1.329@acm.org> <u9pvtnuemu.fsf@yorick.cygnus.com> <33a5f9a1.5157214@news.ipswich.gil.com.au> <u9k9jsuawy.fsf@yorick.cygnus.com> <33a87d7b.3835586@news.ipswich.gil.com.au>
X-Original-Date: 19 Jun 1997 18:25:37 -0700
Organization: Cygnus Solutions, Sunnyvale, CA
X-Auth: PGPMoose V1.1 PGP comp.std.c++ iQBVAwUBM6q7uUy4NqrwXLNJAQFLGQH9HFYE0V9Rkf9Xtwf7bXciF7D6oAHRUHWi p2ORLBYe4q27EL2qHU9NVo5eMHL1dNk3WBfaYpdebAYq4d+r7rXn7g== =cE0N
Newsgroups: comp.std.c++
Originator: austern@isolde.mti.sgi.com


>>>>> Brian Parker <bparker@gil.com.au> writes:

> On 18 Jun 97 02:15:53 GMT, Jason Merrill <jason@cygnus.com> wrote:

>> In this testcase, the problem occurs because even though 'v' is not
>> directly used after the call, references to data it controls are.  This
>> would not be a problem if 'v' went out of scope immediately after the
>> call, because any references to its data are undefined after it goes out of
>> scope.

> Unless some garbage collection scheme is used such that some of the
> object's dynamically-allocated memory is retained beyond the local
> scope (or if the object uses some global memory in its implementation-
> see the MV++ example)

I'm talking about a basic principle here: when the life of an object
expires, references to its contents are undefined.  A garbage-collected
object is not 'automatic', so it doesn't matter to the issue at hand.
Let's talk about this version of C++.

Any global memory the object uses is not "data it controls".  The problem
with the MV++ testcase is, as I have said before, that it relies on the
copy constructor to create a real array out of a fake array, which is too
clever by half.  MV++ should use proxy classes.

> However, as I have shown elsewhere in this thread, the same issues
> arise with the NRVO and RVO, albeit in a much more limited way. In
> particular, the problem examples involve designs which don't maintain
> a strict separation of value and reference semantics. 

Yes.

> Whilst these examples may be of little significance now, one of my
> concerns is that as automatic garbage collection becomes more widely used
> then these problems with the (N)RVO will become more widespread

Again, objects subject to garbage collection are presumably allocated with
'new' and destroyed (by the collector) with 'delete', so 12.8p15 does not
apply to them.

> (N.B. although garbage collection is strictly outside of the standard,
> AFAIK it is at least supposed to be tolerant of it).

It is possible write a conservative collector and use it in conformant
C++.  Changing 'automatic' variables to have garbage-collection semantics,
on the other hand, is such a wild departure from the standard that I can't
imagine it ever happening without changing the name of the language to
something with "Java" in it.

> As an aside, I wonder if anyone is aware of other garbage-collected
> languages that support value semantics class objects, where these same
> issues would arise?

As I understand it, in a garbage-collected language like Java you almost
never return anything by copying it; what would be the point?  When you
create a new matrix in your plus method, you just return a reference to the
new matrix, because it's garbage-collected.  It won't get destroyed at the
end of the function like a C++ auto variable, and the caller doesn't have
to worry about deleting it, like a C++ dynamically allocated object.  The
issues we are discussing here simply don't crop up.

In summary, garbage collection is irrelevant to this discussion.

> Just some further comments on the actual wording-

> (1) It should be limited to copies using the copy constructor only-
> copy assignment operator calls are never implicitly created by the
> compiler and hence shouldn't be elidable.

Hmm...I had assumed that 12.8/15 already only applied to the copy
constructor, but I guess I was wrong.  I don't see any compelling reason
for it to apply to the copy assignment operator, so OK.

> (2) By my reading, 12.8/15 is also used to elide copies of tempoaries
> on initialisation. e.g.

True.  I think my wording almost allows those, too, but it needs to use
something like "lifetime expires" instead of "block exits".

> (Note that in same way that the (N)RVO can cause unexpected behaviour,
> so can the above optimisation, so ideally it too should not be applied
> in unsafe cases such as the MV++ example.)

Ideally unsafe code such as MV++ should not be written.

Next try:

15Whenever a class object is copied and the original object and the copy
  have the same type, and the lifetime of the original object ends
  immediately* after the copy is created, an implementation is permitted to
  treat the original and the copy as two different ways of referring to the
  same object and not perform a copy at all.  In that case, the object is
  destroyed when the copy would have been destroyed without the
  optimization.

* For the purposes of this rule, implicit destructor calls are not
  considered in the lifetime of an object.

Jason
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your 
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu 
]



