Topic: elided constructors (and return value optimization)
Author: "Melissa O'Neill" <NoOnSePiAlMl@cs.sfu.ca>
Date: 1998/11/21 Raw View
Gabriel Dos Reis wrote:
>> I find it unfortunate for the numerical computing community that the
>> return value optimization isn't widely implemented (and in some sense
>> mandatory).
... and Valentin Bonnard <bonnardv@pratique.fr> replied:
> I consider a pity the fact that gcc implemented a language extension
> instead of an optimisation. [...]
>
> - an optimisation is potential cheaper to implement than
> a language change
>
> - optimisations are programmer friendly, extensions
> generally aren't
>
> - language changes can create problems in the long term,
> optimisations don't
>
> I don't understand at all why the language change was chosen over the
> optimisation.
The problem with optional optimizations is that you can't rely on them.
In some situations, not performing the optimization will simply slow
down the code a little, but it's quite easy to conceive of code that
breaks when return value optimization is not applied.
For example, suppose you have a `Connection' class for some kind of
socket/pipe/communications-link, where the destructor for the Connection
closes the connection. Because `Connection's represent unique external
objects, it is meaningless to try to duplicate a `Connection'.
If the semantics of return value optimization were standard behaviour,
rather than optional, you could have a declaration like:
Connection secret_link = open_connection_to_backoffice(my_password);
// ^-- function that returns a Connection
... and be sure that secret_link would be initialized via direct
initialization, rather than copy initialization (in fact, `Connection'
wouldn't need a copy constructor, which would reflect the nature of
connections as unique external objects).
It's important that secret_link be initialized directly, because, if
it is copied and the original is disposed of, the destructor will be
called on the original and the communications link closed prematurely.
F It is possible to work around this issue. One standard solution is
o to use a procedure with reference argument, rather than a function:
o
t Connection secret_link;
n open_connection_to_backoffice(&secret_link, my_password);
o
t ... and another is to implement a smart, ownership transferring copy
e constructor, thereby getting object behaviour much like that of
auto_ptr. The link is only closed when the object that owns the
link is destroyed.
My point is not that there aren't solutions, but it's one of those
things where some programmers may rely on RVO being performed, and
then get caught out when it isn't.
The GNU extension, ugly as it is, has semantics that apply all the
time, rather than at the whim of the optimizer and its authors.
Melissa.
(To reply to this message, remove `N O S P A M' from my email address.)
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]