Topic: Named Return Values in C++
Author: d96-mst@nada.kth.se (Mikael St ldal)
Date: 1996/12/10 Raw View
In article <5821sj$n93@toralf.uib.no>,
boukanov@sentef2.fi.uib.no (Igor Boukanov) wrote:
>X m () return r; {
> r.a = 23;
>}
If something like this is to be included in the C++ standard, I propose
that a new keyword is defined (say "retval") that can be used like
this:
X m()
{
retval.a = 23;
return retval;
}
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: ark@research.att.com (Andrew Koenig)
Date: 1996/12/11 Raw View
In article <eUKqyEpfhqXe090yn@nada.kth.se> d96-mst@nada.kth.se (Mikael St ldal) writes:
> If something like this is to be included in the C++ standard, I propose
> that a new keyword is defined (say "retval") that can be used like
> this:
> X m()
> {
> retval.a = 23;
> return retval;
> }
The standard will have something very much like that. The only difference
is that instead of `retval' being a fixed keyword, you will have to choose
what name to use to represent it.
Because `retval' has the same type as the return value of the function,
the way to designate it has a syntax that looks a lot like a declaration
of a variable of that type:
X m()
{
X retval;
retval.a = 23;
return retval;
}
This syntax has the advantage that it does not require any extra work
on the part of the standards committee to define a new syntax.
--
--Andrew Koenig
ark@research.att.com
---
[ 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
]
Author: boukanov@sentef2.fi.uib.no (Igor Boukanov)
Date: 1996/12/05 Raw View
GCC 2.7.2 has the feature that can significantly increase a performance of
GCC-generated code with functions that return an class.
Here the text from GCC documentation,the full version is available at
http://www.nbi.dk/~pushkin/doc/gcc/gcc_toc.html#SEC99,
-----------------------------------------------------------------------------
GNU C++ extends the function-definition syntax to allow you to specify
a name for the result of a function outside the body of the definition,
in C++ programs:
type functionname (args) return resultname; {
...
body
...
}
You can use this feature to avoid an extra constructor call when a function
result has a class type. For example, consider a function m, declared as
`X v = m ();', whose result is of class X:
X m () {
X b;
b.a = 23;
return b;
}
Although m appears to have no arguments, in fact it has one implicit argument:
the address of the return value. At invocation, the address of enough space
to hold v is sent in as the implicit argument. Then b is constructed and
its a field is set to the value 23. Finally, a copy constructor
(a constructor of the form `X(X&)') is applied to b,
with the (implicit) return value location as the target,
so that v is now bound to the return value.
But this is wasteful. The local b is declared just to hold something that
will be copied right out. While a compiler that combined an "elision"
algorithm with interprocedural data flow analysis could conceivably eliminate
all of this, it is much more practical to allow you to assist the compiler
in generating efficient code by manipulating the return value explicitly,
thus avoiding the local variable and copy constructor altogether.
Using the extended GNU C++ function-definition syntax, you can avoid the
temporary allocation and copying by naming r as your return value at the
outset, and assigning to its a field directly:
X m () return r; {
r.a = 23;
}
The declaration of r is a standard, proper declaration, whose effects are
executed before any of the body of m.
...
This extension is provided primarily to help people who use overloaded
operators, where there is a great need to control not just the arguments,
but the return values of functions. For classes where the copy constructor
incurs a heavy performance penalty (especially in the common case where there
is a quick default constructor), this is a major savings. The disadvantage of
this extension is that you do not control when the default constructor
for the return value is called: it is always called at the beginning.
-----------------------------------------------------------------------------
The questions is how useful this feature with, say, a state-of-art C++
complier, i.e. can such compiler in principle eliminate the need in this
extension in all useful cases under current DWP?
--
Regards, Igor Boukanov.
igor.boukanov@fi.uib.no
http://www.fi.uib.no/~boukanov/
---
[ 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
]
Author: Jason Merrill <jason@cygnus.com>
Date: 1996/12/06 Raw View
>>>>> Igor Boukanov <boukanov@sentef2.fi.uib.no> writes:
> GNU C++ extends the function-definition syntax to allow you to specify
> a name for the result of a function outside the body of the definition,
> ...
> The questions is how useful this feature with, say, a state-of-art C++
> complier, i.e. can such compiler in principle eliminate the need in this
> extension in all useful cases under current DWP?
I think so. This is a quality of implementation issue; g++ does not
currently do this optimization by itself, but it allows the user to do it
explicitly. This extension should be phased out eventually.
Given:
Vector
operator+ (Vector a, Vector b)
{
Vector tmp = a;
for (int i = 0; i < tmp.size(); ++i)
tmp[i] += b[i];
return tmp;
}
the compiler should be able to see that `tmp' is the only returned
expression, so it can live in the stack slot that most ABIs allocate for
large structure returns. I believe that the following passage allows this
optimization, by allowing the compiler to avoid calling the destructor for
`tmp':
12.8 Copying class objects [class.copy]
15Whenever a class object is copied and the original object and the copy
have the same type, if the implementation can prove that either the
original object or the copy will never again be used except as the
result of an implicit destructor call (_class.dtor_), an implementa-
tion 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 at the later of times when the
original and the copy would have been destroyed without the
optimization.107)
Jason
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]