Topic: Zero Unnecessary Temporary Objects: A Revolution
Author: junkmacc1@hotmail.com ("Willow Schlanger (junkmacc1)")
Date: Wed, 30 Oct 2002 10:22:22 +0000 (UTC) Raw View
Alf P. Steinbach wrote:
> On Sat, 12 Oct 2002 05:52:38 +0000 (UTC), bob.news@gmx.net (Robert Klemme) wrote:
>
>
>>
>>Andrei Alexandrescu schrieb:
>>
>>>because we know a temporary might be created, which might pretty much ruin
>>>the performance of the application. Even if we could count on a compiler
>>>implementing RVO (which is not guaranteed nor implemented everywhere nor
>>>supported in similar forms on most compilers), the following is /guaranteed/
>>>to create an unnecessary temporary, even though there's no need for it:
>>>
>>>extern vector<string> Fun();
>>>...
>>>vector<string> v;
>>>...
>>>v = Fun();
>>>
>>>To get rid of that, we have to recourse to the damned hack:
>>>
>>>Fun().swap(v);
I already posted something explaining a cooler way to get rid of the
temporary, but I don't see it here, for some reason. I'll re-post part
of it below (probably my posting was too long):
[snip]
Exhibit C1
---------- -----------------
struct s
{
int x[1024];
};
extern s g();
struct s_g : s
{
s_g()
{
s &t = *this;
t.x[0] = t.x[1023] = 0;
}
};
s g()
{
return s_g();
}
int main()
{
s p;
p = g();
return 0;
}
---------- End of Exhibit C1
And observe the assembly-language code produced:
[snip]
As you can see, the compiler now acts as if the code in Exhibit B1 were
written, yet the semantics of g() is now such that "p = g()" can be used!
We now have the safety and efficiency of g() having the prototype "s g();"
....
I'll re-post my whole tihng under a subject beginning with "Some C/C++
Optimization Idioms I Wish Compilers Supported," where you can learn
about this.
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: alf_p_steinbach@yahoo.no.invalid (Alf P. Steinbach)
Date: Wed, 30 Oct 2002 20:28:36 +0000 (UTC) Raw View
On Wed, 30 Oct 2002 10:22:22 +0000 (UTC), junkmacc1@hotmail.com ("Willow Schlanger
(junkmacc1)") wrote:
>Alf P. Steinbach wrote:
>> On Sat, 12 Oct 2002 05:52:38 +0000 (UTC), bob.news@gmx.net (Robert Klemme) wrote:
>>
>>
>>>
>>>Andrei Alexandrescu schrieb:
>>>
>>>>because we know a temporary might be created, which might pretty much ruin
>>>>the performance of the application. Even if we could count on a compiler
>>>>implementing RVO (which is not guaranteed nor implemented everywhere nor
>>>>supported in similar forms on most compilers), the following is /guaranteed/
>>>>to create an unnecessary temporary, even though there's no need for it:
>>>>
>>>>extern vector<string> Fun();
>>>>...
>>>>vector<string> v;
>>>>...
>>>>v = Fun();
>>>>
>>>>To get rid of that, we have to recourse to the damned hack:
>>>>
>>>>Fun().swap(v);
Nothing of my (old and now irrelevant, Mojo is now public) posting quoted
here.
>I already posted something explaining a cooler way to get rid of the
>temporary, but I don't see it here, for some reason. I'll re-post part
>of it below (probably my posting was too long):
>
>[snip]
>
>Exhibit C1
>---------- -----------------
>struct s
>{
> int x[1024];
>};
>
>extern s g();
Serves no useful purpose, AFAICS.
>struct s_g : s
>{
> s_g()
> {
> s &t = *this;
> t.x[0] = t.x[1023] = 0;
> }
>};
Requires s to have a default constructor.
>s g()
>{
> return s_g();
>}
Slice, but so what?
>
>int main()
>{
> s p;
> p = g();
>
> return 0;
>}
>---------- End of Exhibit C1
>
>And observe the assembly-language code produced:
A compiler *may* choose to construct p in place, if there isn't some
obscure rule in the standard that forbids it. It's not a guaranteed
optimization. Try it out with
s g(){ return s(); }
>[snip]
Huh, snipped your own posting???
>As you can see, the compiler now acts as if the code in Exhibit B1 were
>written, yet the semantics of g() is now such that "p = g()" can be used!
>
>We now have the safety and efficiency of g() having the prototype "s g();"
>
>....
>
>I'll re-post my whole tihng under a subject beginning with "Some C/C++
>Optimization Idioms I Wish Compilers Supported," where you can learn
>about this.
Exactly what is this idiom?
Cheers,
- Alf
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: eldiener@earthlink.net ("Edward Diener")
Date: Tue, 15 Oct 2002 18:31:46 +0000 (UTC) Raw View
Would you explain what, if any, are the advantages of your innovation
outside of the space issues ? I am not trying to discourage you from working
on your idea and being innovative in general, but I do not understand what
your innovation adds to the C++ language/library itself.
""Andrei Alexandrescu"" <andrei@cs.washington.edu> wrote in message
news:H3xKLD.106J@beaver.cs.washington.edu...
> "John Potter" <jpotter@falcon.lhup.edu> wrote in message
> news:3da7f610.55075859@news.earthlink.net...
> > We did not get rid of the (possibly) 12 byte temporary, but we did get
> > rid of the copy of the huge internal array of strings. Looks like
> > reference counted vector without the overhead. With some
> > optimizations we could get rid of the 12 bytes using
> >
> > vector<string> v(Fun());
> >
> > but that is not the point. However, it may be the point which makes
> > ZUTO a joke rather than a revolution. The 12 bytes is a necessary
> > temporary.
>
> Heh :o). Actually ZUTO is a bit of a misnomer, because it is "Zero
> Unnecessary /Copying/ of Temporary Objects". But ZUCTO is not that nice of
a
> name :o).
>
> Zuto works by enabling move construction. It is true there are classes for
> which move construction doesn't work, for example:
>
> class Matrix
> {
> double data_[128][128];
> ...
> };
>
> For this kind of data, ZUTO can't help. If I understand it correctly, the
> move constructor proposal would not help, either.
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: andrewalex@hotmail.com ("Andrei Alexandrescu")
Date: Sat, 12 Oct 2002 09:32:39 +0000 (UTC) Raw View
"Robert Klemme" <bob.news@gmx.net> wrote in message
news:3DA6DD42.E901E297@gmx.net...
> > extern vector<string> Fun();
> > ...
> > vector<string> v;
> > ...
> > v = Fun();
> >
> > To get rid of that, we have to recourse to the damned hack:
> >
> > Fun().swap(v);
>
> why does this get rid of the temporary? isn't the temp created
> before swap() is invoked? then, what do we gain?
It is a temporary, but it's not "unnecessary" anymore because it is moved
into the destination (as opposed to copying).
Andrei
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: alf_p_steinbach@yahoo.no.invalid (Alf P. Steinbach)
Date: Sun, 13 Oct 2002 04:04:56 +0000 (UTC) Raw View
On Sat, 12 Oct 2002 05:52:38 +0000 (UTC), bob.news@gmx.net (Robert Klemme) wrote:
>
>
>Andrei Alexandrescu schrieb:
>> because we know a temporary might be created, which might pretty much ruin
>> the performance of the application. Even if we could count on a compiler
>> implementing RVO (which is not guaranteed nor implemented everywhere nor
>> supported in similar forms on most compilers), the following is /guaranteed/
>> to create an unnecessary temporary, even though there's no need for it:
>>
>> extern vector<string> Fun();
>> ...
>> vector<string> v;
>> ...
>> v = Fun();
>>
>> To get rid of that, we have to recourse to the damned hack:
>>
>> Fun().swap(v);
>
>why does this get rid of the temporary? isn't the temp created
>before swap() is invoked? then, what do we gain?
I don't think Andrei meant that; I think he meant that use of
swap got rid of the obstacle to RVO, the guarantee of an unneccessary
temporary, that obstacle presumably being the assignment -- without
necessarily getting rid of the temporary (RVO would do that).
One difference between swap and assignment is that swap takes
the vector as non-const reference. I don't quite see how that
in itself would help. I'd rather assume the opposite.
Another difference is that swap may be simple enough that the
compiler understands its semantics. In which case it might
implement "Fun().swap(v)" as e.g. "v.clear(); Fun( &v );",
where the Fun() parameter is a hidden one for RVO. Well, if
this is the case, then I can understand that cryptic comment about
perhaps having hit onto some compiler bug or extension.
<speculation>
In order to make this independent of the compiler's support for
RVO or not one would have to explicitly pass the "RVO" parameter
always for a function returning non-simple type.
Calling a function would then be somewhat awkward unless one
packaged the call in a functor object, "v = Call( Fun )",
where Call( Fun ) is a constructor call on functor class Call.
Here it gets somewhat complicated to analyze because in order
to have assignment automatically use the functor (it seems
to me) one would have to delay the function call until the
execution of the body of the assignment operator, which would
have to pass the "RVO" parameter to the functor object. One
question is then, what about function calls outside the context
of an assignment? Well, for a function with return type T one
could endow the functor object with conversion to T (in an
assignment the assignment operator would take the functor
object directly, not invoking the conversion). The question is
then, with inlining of things, will a normal compiler be able to
optimize away the functor object?
</speculation>
Ok, that's my speculation for now... ;-)
Cheers,
- Alf
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: Sun, 13 Oct 2002 04:05:36 +0000 (UTC) Raw View
On Sat, 12 Oct 2002 05:52:38 +0000 (UTC), bob.news@gmx.net (Robert
Klemme) wrote:
> Andrei Alexandrescu schrieb:
> > extern vector<string> Fun();
> > ...
> > vector<string> v;
> > ...
> > v = Fun();
At this point, a copy of the temporary is made in v and then the
temporary is destroyed.
> > To get rid of that, we have to recourse to the damned hack:
> > Fun().swap(v);
In this case, the empty v and the temporary are swapped. The
temporary which is destroyed is now empty.
> why does this get rid of the temporary? isn't the temp created
> before swap() is invoked? then, what do we gain?
We did not get rid of the (possibly) 12 byte temporary, but we did get
rid of the copy of the huge internal array of strings. Looks like
reference counted vector without the overhead. With some
optimizations we could get rid of the 12 bytes using
vector<string> v(Fun());
but that is not the point. However, it may be the point which makes
ZUTO a joke rather than a revolution. The 12 bytes is a necessary
temporary.
John
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: wolof@freemail.hu ("White Wolf")
Date: Sun, 13 Oct 2002 05:54:33 +0000 (UTC) Raw View
"Robert Klemme":
>
> Andrei Alexandrescu schrieb:
> > because we know a temporary might be created, which might pretty much
ruin
> > the performance of the application. Even if we could count on a
compiler
> > implementing RVO (which is not guaranteed nor implemented everywhere
nor
> > supported in similar forms on most compilers), the following is
/guaranteed/
> > to create an unnecessary temporary, even though there's no need for it:
> >
> > extern vector<string> Fun();
> > ...
> > vector<string> v;
> > ...
> > v = Fun();
> >
> > To get rid of that, we have to recourse to the damned hack:
> >
> > Fun().swap(v);
>
> why does this get rid of the temporary? isn't the temp created
> before swap() is invoked? then, what do we gain?
Of course it does not.
Of ourse it is created.
Copying. This will swap the pointers inside the vectors _only_ thereby
making the v to contain the elements returned by Fun() and making the
unnamed temporary to contain nothing (whatever way the vector represents
that in the implementation). It is the largest saving without the RVO
making it a non-const reference argument instead of return value. But that
is PiTA and requires a cleanup of the vector before each operation.
This is an example how things are solved today. As far as I understood
this is not the ZUTO.
WW
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: a9804814@unet.univie.ac.at (Thomas Mang)
Date: Sun, 13 Oct 2002 05:54:38 +0000 (UTC) Raw View
Allan W schrieb:
> andrewalex@hotmail.com ("Andrei Alexandrescu") wrote
> >
> > I believe I have hacked together a complete solution for eliminating
> > unnecessary temporary objects in C++. The topic relates to the heavy
> > discussions on move constructors, too. The solution (let's call it ZUTO
> > (Zero Unnecessary Temporary Objects) henceforth) has the following
> > characteristics:
>
> You make it sound like you've already done this. A web search for ZUTO
> produced a surprising number of hits -- well over 10,000, IIRC -- but
> they didn't seem related to C++. Attempts to refine the search came
> up fruitless.
>
> Have you described it in more detail elsewhere? If it really does
> everything you say -- well, I'd like to know more about it.
And maybe it turns out to be something like:
class Matrix
{
};
Matrix operator+(const Matrix& m1, const Matrix& m2)
{
Matrix temp(m1);
return temp += m2;
}
this will now be transformed into something like:
voi Matrix::operator+(const Matrix& m1, const Matrix& m2, void* targetMem)
{
// copy all bits from "m1" to "targetMem"
// apply to this operator+=(m2)
}
and the client code:
m = m1 + m2;
Now gets transformed by the compiler into:
operator+(m1, m2, &m)
and voila, no temporary.
works almost anywhere, where during the creation of the temporary no special
side effects occurr:
Instead of returning a temporary, take the address of the destination as an
argument, and place the result right into this, returning nothing.
cheers,
thomas
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Sun, 13 Oct 2002 09:38:41 +0000 (UTC) Raw View
> "Robert Klemme" <bob.news@gmx.net> wrote
> > > Fun().swap(v);
> >
> > why does this get rid of the temporary? isn't the temp created
> > before swap() is invoked? then, what do we gain?
andrewalex@hotmail.com ("Andrei Alexandrescu") wrote
> It is a temporary, but it's not "unnecessary" anymore because it is moved
> into the destination (as opposed to copying).
Under that definition, we could get rid of all unnecessary copying by
adding the following line into the standard:
Assignments always create temporary objects which may not be
elided.
And there you have it -- temporary objects are never unnecessary anymore.
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: wolof@freemail.hu ("White Wolf")
Date: Sun, 13 Oct 2002 16:17:17 +0000 (UTC) Raw View
"Allan W":
> Under that definition, we could get rid of all unnecessary copying by
> adding the following line into the standard:
>
> Assignments always create temporary objects which may not be
> elided.
>
> And there you have it -- temporary objects are never unnecessary anymore.
Do you means that if we pass a low that everyone who calls himself Allan W
and posts to clc++mod should wear a 40kgs per foot moon-boot it will not
mean it is unnecessary for you to wear it? Is it just my feeling that you
have left out the smiley? I beleive if you pass such
impractical/unnecessary things into the standard (thereby violating one of
the most fundamental axioms of C++) you make no service to anyone. If you
put a smiley - I get it. If not - it sound like a bad joke. We already
have too many places in C++ where unwanted (and that is the right word:
only a dead temporary is a good temporary) temporaries show their ugly
temporary faces.
--
--
White Wolf aka Attila @ LMF
ICQ#: 26070936
http://wwp.icq.com/26070936
If I'm not online send mail.
NO USENET followups please.
SPAM is not welcome.
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: bob.news@gmx.net (Robert Klemme)
Date: Mon, 14 Oct 2002 12:54:19 +0000 (UTC) Raw View
White Wolf schrieb:
> We already
> have too many places in C++ where unwanted (and that is the right word:
> only a dead temporary is a good temporary) temporaries show their ugly
> temporary faces.
well, at least the ugly faces are only temporary - i can live
with that... :-))
robert
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: andrei@cs.washington.edu ("Andrei Alexandrescu")
Date: Mon, 14 Oct 2002 15:05:03 +0000 (UTC) Raw View
"John Potter" <jpotter@falcon.lhup.edu> wrote in message
news:3da7f610.55075859@news.earthlink.net...
> We did not get rid of the (possibly) 12 byte temporary, but we did get
> rid of the copy of the huge internal array of strings. Looks like
> reference counted vector without the overhead. With some
> optimizations we could get rid of the 12 bytes using
>
> vector<string> v(Fun());
>
> but that is not the point. However, it may be the point which makes
> ZUTO a joke rather than a revolution. The 12 bytes is a necessary
> temporary.
Heh :o). Actually ZUTO is a bit of a misnomer, because it is "Zero
Unnecessary /Copying/ of Temporary Objects". But ZUCTO is not that nice of a
name :o).
Zuto works by enabling move construction. It is true there are classes for
which move construction doesn't work, for example:
class Matrix
{
double data_[128][128];
...
};
For this kind of data, ZUTO can't help. If I understand it correctly, the
move constructor proposal would not help, either.
Andrei
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: andrei@cs.washington.edu ("Andrei Alexandrescu")
Date: Mon, 14 Oct 2002 16:48:21 +0000 (UTC) Raw View
"Allan W" <allan_w@my-dejanews.com> wrote in message
news:7f2735a5.0210130056.40e15098@posting.google.com...
> andrewalex@hotmail.com ("Andrei Alexandrescu") wrote
> > It is a temporary, but it's not "unnecessary" anymore because it is
moved
> > into the destination (as opposed to copying).
>
> Under that definition, we could get rid of all unnecessary copying by
> adding the following line into the standard:
>
> Assignments always create temporary objects which may not be
> elided.
>
> And there you have it -- temporary objects are never unnecessary anymore.
I should have known better than posting cocky messages to clc++m :o).
But don't forget that ZUTO works without asking for ANY change in the
Standard - even that mentioned by yourself :oD.
Andrei
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hinnant@metrowerks.com (Howard Hinnant)
Date: Mon, 14 Oct 2002 16:51:19 +0000 (UTC) Raw View
In article <H3xKLD.106J@beaver.cs.washington.edu>, Andrei Alexandrescu
<andrei@cs.washington.edu> wrote:
| class Matrix
| {
| double data_[128][128];
| ...
| };
|
| For this kind of data, ZUTO can't help. If I understand it correctly, the
| move constructor proposal would not help, either.
That's correct (about the move proposal not helping here either).
--
Howard Hinnant
Metrowerks
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Mon, 14 Oct 2002 17:14:16 +0000 (UTC) Raw View
> "Allan W":
> > Under that definition, we could get rid of all unnecessary copying by
> > adding the following line into the standard:
> >
> > Assignments always create temporary objects which may not be
> > elided.
> >
> > And there you have it -- temporary objects are never unnecessary anymore.
wolof@freemail.hu ("White Wolf") wrote
> Do you means that if we pass a low that everyone who calls himself Allan W
> and posts to clc++mod should wear a 40kgs per foot moon-boot it will not
> mean it is unnecessary for you to wear it? Is it just my feeling that you
> have left out the smiley? I beleive if you pass such
> impractical/unnecessary things into the standard (thereby violating one of
> the most fundamental axioms of C++) you make no service to anyone. If you
> put a smiley - I get it. If not - it sound like a bad joke. We already
> have too many places in C++ where unwanted (and that is the right word:
> only a dead temporary is a good temporary) temporaries show their ugly
> temporary faces.
You mostly got it. I wasn't making a joke -- I wasn't especially trying
for humor. But I was trying to make a point by pointing out a logical
absurdity. So you're quite right that I wouldn't really want this rule
added to the next standard.
Taking an argument to it's logical absurdity has been an argument
technique for at least 2000 years, and probably even longer. They are
commonly used in formal mathematical proofs. For instance, the easiest
way to prove that you can't divide a number by zero, is to assume that
division by zero WAS defined, and then go on to prove that 0=1. Since
we all know that 0!=1, we are forced to conclude that the original
premise is invalid, i.e. division by zero is NOT defined.
I hope you see now why I made such a statement without a smiley -- I
was trying to show (without rigorous proof) that the original premise
was not valid, at least not in all situations.
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: andrewalex@hotmail.com ("Andrei Alexandrescu")
Date: Thu, 10 Oct 2002 23:16:55 +0000 (UTC) Raw View
Hello,
This is a request for a favor.
I believe I have hacked together a complete solution for eliminating
unnecessary temporary objects in C++. The topic relates to the heavy
discussions on move constructors, too. The solution (let's call it ZUTO
(Zero Unnecessary Temporary Objects) henceforth) has the following
characteristics:
1. It does not require language changes.
2. Has no or minimal impact on client code. In many cases, elimination of
many temporary objects is achieved by changing the offending class
definition and recompiling client code. To /totally/ eliminate temporary
objects (and I mean /totally/), client code has only to perform a minor
change when returning lvalues from functions.
3. Lends itself to a library implementation accompanied by simple idioms.
4. Is guaranteed, i.e., you're not at the mercy of a fragile RVO (Return
Value Optimization) implementation which might or might not kick in.
5. Works in all cases, whereas RVO works only in certain cases.
6. Does not require ugly client syntax nor ugly class definition syntax.
(Your mileage might vary for the latter.)
7. Does not do advanced temporary elimination a la loop fusion, which is
solved by using expression templates. (Fortunately, ZUTO is at least much
simpler than expression templates.) So it could be said ZUTO does eliminate
all unnecessary temporaries, for a reasonable definition of "unnecessary"
:o).
8. ZUTO is likely to be supported by all compilers that know enough to
compile std::auto_ptr.
We all are aware of the nuisance that unnecessary temporary objects are. We
are afraid to write elegant code such as:
extern vector<string> Fun();
...
vector<string> v = Fun();
because we know a temporary might be created, which might pretty much ruin
the performance of the application. Even if we could count on a compiler
implementing RVO (which is not guaranteed nor implemented everywhere nor
supported in similar forms on most compilers), the following is /guaranteed/
to create an unnecessary temporary, even though there's no need for it:
extern vector<string> Fun();
...
vector<string> v;
...
v = Fun();
To get rid of that, we have to recourse to the damned hack:
Fun().swap(v);
Furthermore, when passing Fun's result to some function, again an
unnecessary temporary can be created. And so on.
The hack I'm telling about solves all the problems above in a manner that I
believe is elegant enough to deserve attention. I will first talk about it
at The C++ Seminar (see my sig). The implications in C++ idioms, class
design, coding standards, and maybe even compiler design, are possibly quite
deep. Here are some examples:
* One can now design an auto_ptr that does what auto_ptr is designed to do,
but without any of its horrible caveats. In particular, the newly-designed
auto_ptr can be safely stored in certain containers. Any wrongful use will
be flagged at compile time.
* The recommended conventions for passing values to and returning values
from functions might change forever.
* Here are current state-of-the-art recommended canonic signatures and
implementations of some primitive functions:
class T
{
...
T& operator=(const T& rhs)
{
T copy(rhs);
rhs.swap(*this);
return *this;
}
};
const T operator+(const T& lhs, const T& rhs)
{
T copy(lhs);
return copy += rhs;
}
I reached the conclusion that the signatures and implementations above are
about the worst possible to recommend, with or without ZUTO in action. I
consider them simply wrong.
I tested ZUTO on MSVC.NET Everett Beta and MWCW 7.0, and it screams. It's a
pleasure to run through the debugger and see the temporaries disciplinately
flowing from source to destination without any efficiency hitch.
Exactly because the implications might be so deep, I don't want to make a
fool of myself. Maybe I am making some mistake, or I overlooked something,
or I hit onto some compiler bug or extension. So I wanted to ask for some
volunteers to review my article before it goes out. If there are volunteers,
please write me email. The article will be out in 2 months, and I believe
I'll have something done in a couple of weeks.
Andrei
--
All new! THE C++ Seminar: Oct. 28-30 in Vancouver, WA.
http://www.thecppseminar.com/
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: thurni@bigpond.com ("Nick Thurn")
Date: Fri, 11 Oct 2002 11:49:36 +0000 (UTC) Raw View
""Andrei Alexandrescu"" <andrewalex@hotmail.com> wrote in message
news:ao4t70$iqt0s$1@ID-14036.news.dfncis.de...
> * Here are current state-of-the-art recommended canonic signatures and
> implementations of some primitive functions:
>
> class T
> {
> ...
> T& operator=(const T& rhs)
> {
> T copy(rhs);
> rhs.swap(*this);
> return *this;
> }
> };
>
Hey Andrei,
Did you mean
class T
{
T& operator=(const T& rhs)
{
T copy(rhs);
copy.swap(*this);
return *this;
}
};
I suspect yes. In any case ZUTO sounds great. When will you
post the details?
cheers
Nick
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: andrei@cs.washington.edu ("Andrei Alexandrescu")
Date: Fri, 11 Oct 2002 17:42:46 +0000 (UTC) Raw View
""Nick Thurn"" <thurni@bigpond.com> wrote in message
news:T0tp9.50623$g9.146837@newsfeeds.bigpond.com...
> Did you mean
>
> class T
> {
> T& operator=(const T& rhs)
> {
> T copy(rhs);
> copy.swap(*this);
> return *this;
> }
> };
>
> I suspect yes.
Indeed; apologies for the typo.
> In any case ZUTO sounds great. When will you
> post the details?
First, I can't do anything before The C++ Seminar, because it's "all new"
material. Then, I prefer to make available a polished, clearly expressed
version instead of the clutter that's now in my mind. Just kidding. Ok, half
kidding.
By the way, in only less than 24 hours there's been a fantastic turnaround.
There are 36 volunteers already. The interest is huge. I feel like that guy
who claimed can compress any file into 1024 bytes :o).
Andrei
--
All new! THE C++ Seminar: Oct. 28-30 in Vancouver, WA.
http://www.thecppseminar.com/
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: wolof@freemail.hu ("White Wolf")
Date: Fri, 11 Oct 2002 19:25:49 +0000 (UTC) Raw View
""Andrei Alexandrescu"":
[SNIP]
> By the way, in only less than 24 hours
> there's been a fantastic turnaround.
When do you plan to send out something? (I was one of the volume-tears :-)
> There are 36 volunteers already. The interest is huge.
Yeh yeh. When do I (OK, OK: we) get it? ;-)
> I feel like that guy
> who claimed can compress any file into 1024 bytes :o).
With a lossy compression... :-)
WW
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Fri, 11 Oct 2002 23:59:55 +0000 (UTC) Raw View
andrewalex@hotmail.com ("Andrei Alexandrescu") wrote
>
> I believe I have hacked together a complete solution for eliminating
> unnecessary temporary objects in C++. The topic relates to the heavy
> discussions on move constructors, too. The solution (let's call it ZUTO
> (Zero Unnecessary Temporary Objects) henceforth) has the following
> characteristics:
You make it sound like you've already done this. A web search for ZUTO
produced a surprising number of hits -- well over 10,000, IIRC -- but
they didn't seem related to C++. Attempts to refine the search came
up fruitless.
Have you described it in more detail elsewhere? If it really does
everything you say -- well, I'd like to know more about it.
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: bob.news@gmx.net (Robert Klemme)
Date: Sat, 12 Oct 2002 05:52:38 +0000 (UTC) Raw View
Andrei Alexandrescu schrieb:
> because we know a temporary might be created, which might pretty much ruin
> the performance of the application. Even if we could count on a compiler
> implementing RVO (which is not guaranteed nor implemented everywhere nor
> supported in similar forms on most compilers), the following is /guaranteed/
> to create an unnecessary temporary, even though there's no need for it:
>
> extern vector<string> Fun();
> ...
> vector<string> v;
> ...
> v = Fun();
>
> To get rid of that, we have to recourse to the damned hack:
>
> Fun().swap(v);
why does this get rid of the temporary? isn't the temp created
before swap() is invoked? then, what do we gain?
regards
robert
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]