From 8699876605773869585
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f78e5,f5d433881cc29cff
X-Google-Attributes: gidf78e5,public
From: bparker@gil.com.au (Brian Parker)
Subject: Re: Named return value optimisation- reprise.
Date: 1997/06/19
Message-ID: <33a87d7b.3835586@news.ipswich.gil.com.au>#1/1
X-Deja-AN: 251130159
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>
X-Original-Date: Thu, 19 Jun 1997 03:25:22 GMT
Organization: Global Info-Links News Server
X-Auth: PGPMoose V1.1 PGP comp.std.c++ iQBVAwUBM6lZFEy4NqrwXLNJAQHm+wIAqfim8MIGsh/cEIpqUWhARDQGaw/+PBku uHJ3u9fjgMJye3h60jZVp1YQXemB16d6G2UEaPxf5utlB5TTm6eshg== =3YT8
Newsgroups: comp.std.c++
Originator: austern@isolde.mti.sgi.com


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

>>>>>> Brian Parker <bparker@gil.com.au> writes:
>
>> Trouble is, the STL also plays aliasing games. In fact, many classes
>> using dynamically allocated memory would fall prey to the 12.8/5 bugs.
>>  I repeat here a previously posted example using STL (it involves
>> 12.8/5 being used to elide the copy on pass-by-value).
>
>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)

>  Thus, I suggest that 12.8/15 should be reworded to read 
>
>15Whenever an automatic (_basic.stc.auto_) class object is copied and the
>  original object and the copy have the same type, and the block containing
>  the original object exits (_stmt.jump_) 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.
>
>I think this only allows the RVO.

This rewording to limit 12.8/15 to just the NRVO and RVO would render
it much safer, and I think that at a minimum this is necessary.

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. 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
e.g. the STL vector class currently has value semantics, but when a
garbage collector is linked in, people are going to hold onto
iterators of automatic vectors and, rightly, expect the pointed at
memory to be retained beyond the local scope.
(N.B. although garbage collection is strictly outside of the standard,
AFAIK it is at least supposed to be tolerant of 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?  

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.

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

class D {

	D(int) {...};
	D(const D&) { ... };
};

The initialisation, 
D d = 1;

has the semantics-
D d = D(1);
i.e. a temporary D is created which is then copy constructed into d.

I believe that 12.8/15 is needed to allow the common optimisation of
constructing the temporary D directly into d and so eliding a copy,
and so if you want to continue to allow this then some addition words
would need to be added to 12.8/15.
(Actually, I am not certain if 12.8/15 is needed in this case; can
anyone shed some light on this?)

(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.)

,Brian Parker (bparker@gil.com.au)
---
[ 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 
]



