From: tmb@arolla.idiap.ch (Thomas M. Breuel)
Newsgroups: comp.lang.c++
Subject: Re: destruction of temporaries
Date: 22 Aug 92 04:11:31 GMT
	<23466@alice.att.com> <3920@starlab.UUCP> <23487@alice.att.com>
	<TMB.92Aug20142610@arolla.idiap.ch> <23507@alice.att.com>
	<TMB.92Aug21142555@arolla.idiap.ch> <9223502.26462@mulga.cs.mu.OZ.
Reply-To: tmb@idiap.ch
Organization: IDIAP (Institut Dalle Molle d'Intelligence Artificielle
	Perceptive)
In-reply-to: fjh@mundil.cs.mu.OZ.AU's message of 21 Aug 92 16:58:13 GMT


   tmb@arolla.idiap.ch (Thomas M. Breuel) writes:

   >In article <23507@alice.att.com> ark@alice.att.com (Andrew Koenig) writes:
   >
   >   The trouble comes with expressions like
   >
   >	   foo().bar().baz()
   >
   >   where bar returns *this. If an implementation is allowed to delete
   >   the result of foo() before calling baz, the roof can cave in even
   >   if your defensive rules are followed.
   >
   >Read my paragraph again. I explicitly stated you shouldn't return a
   >reference to "*this".

   What about

	   cout << "Hello World" << endl;

   Does this mean that we have to go back to printf?

No, it doesn't mean that. Perhaps I should have been more explicit.

You want to avoid getting dangling references to temporaries.
Generally, the safest way is not to return pointers/references to
arguments of (member) functions.

Tradition and syntax suggest that for a few functions you end up
wanting to do this anyway. Simply try to avoid making a habit of
introducing new functions like this. If you do write them, don't ever
use them with temporaries.

Hence, it's OK to write:

	a = s;
	cout << "Hello World\n";

However, you should worry when you see code like the following
(fortunately, cases like this are syntactically pretty obvious).  You
should worry because you are (hopefully) very aware of the fact that
operator= and operator<< return references:

	(x+y) = s;
	make_stream(1) << "Hello World\n";

If you do want to write something like this (which I have never wanted
to), say instead:

	String temp = x+y;
	temp = s;

	ostream stream = make_stream(1);
	stream << "Hello World\n";

Incidentally, I believe, in principle, "operator<<" could have been
defined to return an "ostream" with appropriate semantics (rather than
an "ostream&"), so that this wouldn't even have been an issue. But
given that "ostream" is almost never a temporary, and that everybody
_knows_ what operator<< returns, the current rule is probably OK
(and more efficient).

All of this is a matter of style, taste, and the particular kinds of
applications you happen to write frequently (I write graphics,
numerical, image processing, user interface, and string code in C++,
so I think my applications are pretty mainstream). All I can say is
that (1) I have not found dangling references to temporaries to be a
major problem (in fact, I had never even considered it to be an
important issue before this discussion--I felt C++ was using the
"obvious" rule within its limitations), (2) trying to make up for the
inefficiencies resulting from late destruction of temporaries seems to
me to be much harder than avoiding dangling references to temporaries,
and (3) even if later destruction of temporaries were adopted, you
still would have to be careful not to get dangling references at the
block/function level--without GC, the problem will not go away.

					Thomas.
Newsgroups: comp.lang.c++