Topic: Death of the Return Value Optimization?
Author: smeyers@netcom.com (Scott Meyers)
Date: 1995/05/27 Raw View
Robert Coie wrote:
The closest wording I found to your concept of "free of side effects" for
ctor/dtors was "trivial constructors" and "trivial destructors", defined
in 12.1 and 12.4. 12.2 verse 3 insures that constructors and destructors
must be called for compiler-generated temporaries of type with non-trivial
constructors or destructors. ... no explicitly defined constructor or
destructor can be trivial ...
12.2 verse 3 is pretty explicit:
When a processor introduces a temporary object of a class that has a
non-trivial constructor (_class.ctor_), it shall ensure that a con-
structor is called for the temporary object. Similarly, the destruc-
tor shall be called for a temporary with a non-trivial destructor
(_class.dtor_). Temporary objects are destroyed as the last step in
evaluating the full-expression (_intro.execution_) that (lexically)
contains the point where they were created. This is true even if that
evaluation ends in throwing an exception.
As far as I can tell, this makes the return value optimization invalid
in virtually all nontrivial cases, and this seems like a Bad Thing to
me. Consider this rather common example:
class String { // I know the library has a string class,
public: // but bear with me here
String(const char *s1,
const char *s2); // "appending ctor": constructs the
// String made by appending s2 to s1
~String(); // somebody has to free the memory
...
};
inline
String operator+(const String& s1, const String& s2)
{
return String(s1, s2);
}
In the past, we could always say that calls to operator+ in contexts
like these,
String result = a + b; // assume a and b are String objects
probably had no cost, because the return value optimization (ARM
12.1.1c) would allow for the object being returned by the function to be
constructed in the memory reserved for result. (Making the function
inline, as the ARM points out, even eliminates the function call, making
the initialization of result about as efficient as possible.)
My reading of 12.2 verse 3 is that this optimization is no longer
valid. I think this would be a step backwards for C++. Am I missing
something? How do others see this? If the rule in the ARM was
intentionally changed, does anybody know why?
Thanks,
Scott
Author: jason@cygnus.com (Jason Merrill)
Date: 1995/05/28 Raw View
>>>>> Scott Meyers <smeyers@netcom.com> writes:
> inline
> String operator+(const String& s1, const String& s2)
> {
> return String(s1, s2);
> }
Seems to me that the temporary in the return statement can be omitted. The
passage you quoted only applies to temporaries that are kept.
Jason
Author: smeyers@netcom.com (Scott Meyers)
Date: 1995/05/28 Raw View
In article <JASON.95May28010202@phydeaux.cygnus.com> jason@cygnus.com (Jason Merrill) writes:
|
| Seems to me that the temporary in the return statement can be omitted. The
| passage you quoted only applies to temporaries that are kept.
This is an encouraging interpretation. Presumably it is based on 12.2 verse 1:
In some circumstances it might be necessary or convenient for the pro-
cessor to generate a temporary object. Precisely when such tempo-
raries are introduced is implementation-defined. Even when the cre-
ation of the temporary object is avoided, all the semantic restric-
tions must be respected as if the temporary object was created.
[Example: even if the copy constructor is not called, all the semantic
restrictions, such as accessibility, shall be satisfied. ]
I would have thought that ctor/dtor side effects were "semantic
restrictions" that had to be preserved, but apparently not. In fact, on
rereading 12.2 verse 2, it is clear that the return value optimization is
still supposed to be allowed.
So now it seems like 12.2 verse 3 means little more than "IF an
implementation introduces a temporary object, it has to behave like an
object."
Scott
Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/05/28 Raw View
smeyers@netcom.com (Scott Meyers) writes:
>So now it seems like 12.2 verse 3 means little more than "IF an
>implementation introduces a temporary object, it has to behave like an
>object."
Well, yes. "When" and "if" mean pretty much the same thing in this
context.
"When you fumigate the house, stay away for 24 hours."
This doesn't mean that I must always stay away from the house.
It means "at such time as" I fumigate the house. I can comply
vacuously by not fumigating the house.
--
Steve Clamage, stephen.clamage@eng.sun.com