From -7802483233931862709
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f78e5,f5d433881cc29cff
X-Google-Attributes: gidf78e5,public
From: Pete Becker <petebecker@acm.org>
Subject: Re: Named return value optimisation- reprise.
Date: 1997/06/15
Message-ID: <33A478C1.329@acm.org>#1/1
X-Deja-AN: 248724523
References: <33a345bf.7425526@news.ipswich.gil.com.au>
X-Original-Date: Sun, 15 Jun 1997 19:20:33 -0400
Organization: Pete Becker Consulting
X-Auth: PGPMoose V1.1 PGP comp.std.c++ iQBVAwUBM6SpVky4NqrwXLNJAQGlxwIAmX8ka/C8pDQ07f75jOuhfJmpLZU7LGkc 2Sh/TucBqqYEwhjVZV1U6r9bVuPqgxxZxifXNjhrZTzs/RO4Lp17QQ== =+G2H
Reply-To: petebecker@acm.org
Newsgroups: comp.std.c++
Originator: austern@isolde.mti.sgi.com


Brian Parker wrote:
> 
> In a recent thread, the virtues and dangers of the named return value
> optimisation were discussed.
> I gave a contrived example which would fail if the named return value
> optimisation was applied, but the general concensus was that the
> example given was badly designed as it confused value and reference
> semantics and hence was of no practical significance.
It's nothing as subtle as confusing value and reference semantics. Don't
try to make this tricky. It's easy. See below.

> 
> I have since noticed an existing well-known matrix class library which
> would fail in a similar (more plausible) example.
> 
> The example follows-
> 
> In the MV++ matrix library (v 1.5 a) there is a matrix class
> MV_Vector_double class which is a vector with value (copy) semantics
> e.g.
> 
> MV_Vector_double A(10);  // length 10 vector
> 
> MV_Vector_double B(A);   // copy of A
> 
> MV_Vector_double C;
> C = A;                  // copy of A
> 
> One can, however, initialise it as a view on an existing C array, so
> that it can be easily used with C code, thus-
> 
> double a[] = {1.0, 2.0, 3.0};
> 
> MV_Vector_double D(a, 3, MV_Vector::ref);
> D[1] = 4.0;     // set a[1] = 4.0;
> 
> Note that this mixing of reference semantics on construction with
> value semantics on copying is, I think, a reasonable design choice-
> this is similar to the built-in references.
> 
> Now we can write a useful function to initialise a vector with a copy
> of a C array-
> 
> double a[] = {1.0, 2.0, 3.0};
> 
> MV_Vector_double Copy_C_array()
> {
>         MV_Vector_double A(a, 3, MV_Vector::ref);
At this point, presumably, A holds a pointer to the array 'a', if I've
got this right.


>         return A;
And at this point, invoking the copy constructor would copy the array
'a' into a distinct array, and put a pointer to that array into the copy
of A. Right?

> }
> 
> MV_Vector_double B = Copy_C_array();
> B[1] = 4.0; // a[1] == 2.0 as B is a copy
> 
> However, if the NRVO is enabled then B will incorrectly be a reference
> to a and hence a[1] == 4.0.
Yes, if the copy construction were skipped then B would hold a pointer
to 'a' instead of holding a pointer to a distinct array. Have I got this
right?
	Skipping the copy constructor is not legal. The object A consists of
the storage allocated for A itself and the array 'a'. Since the array
'a' is being accessed later (in order to see what happens to a[1]), the
compiler is not permitted to eliminate the copy constructor.
	The problem in the analysis of this issue lies in thinking that an
"object" is only the members that we name. This is not correct. It is
the region of memory that holds the data. All of the data, not part of
it.
	-- Pete
---
[ 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 
]



