From: ark@alice.att.com (Andrew Koenig)
Newsgroups: comp.lang.c++
Subject: Re: destruction of temporaries
Date: 18 Aug 92 13:51:10 GMT
Reply-To: ark@alice.UUCP ()
Organization: AT&T Bell Laboratories, Liberty Corner NJ

In article <1992Aug17.211508.6634@lucid.com> jss@lucid.com (Jerry Schwarz) writes:

> And I feel that I should be able to add a { } around an expression
> statement without changing its meaning.  In other words I ought
> to be able to further transform the above to

> 		const char* r = "" ;
> 		if ( 1 ) { r = s+t ; } 
> 		printf("%s\n", r) 

> Even "end of block" (the latest anyone has proposed) makes
> this example undefined.

In other words, no algorithm for destroying temporaries will give
you what you want; what you want is impossible.  This argument is
therefore scarcely relevant.

> ... Early destruction makes many useful idioms impossible. 

Agreed.  The real question is which of the other alternatives is
the best balance between efficiency, difficulty of implementation,
and so on.

> |> 
> |> 	2. It is a real pain to implement for statements that
> |> 	   generate temporaries inside conditionals.  

> Yes, it requires more effort on the part of compiler vendors to get it 
> right,  but a lot less than many other features of C++.  

I don't think so; at least not in the presence of exception handling.
The trouble is that a naive approach can potentially make programs
either big or slow very quickly and optimizing it is hard enough that
compilers are likely to get it wrong in practice.

> It is possible to construct examples where the bookkeeping is a significant
> overhead. But I don't believe this is a substantial problem in practice. 

That's true only if people usually don't write programs for which it
makes a difference, in which case this whole discussion is moot.

> It isn't quite true that it becomes impossible to have a static map.
> The cost of doing so is duplicated code.

The size of the duplicate code is potentially exponential in the size
of the original program; concealing exponential code growth seems to
be a nasty thing to do to a programmer.

> An alternative implementation requires flags in some cases to
> determine which temps have been constructed, and the static
> data structure would have to indicate this. The normal case where there
> is no flag would require no extra overheads.

That's not the point.  The real problem is that now the code that
unwinds exceptions has to know where the flags are and test them.
That means, for example, that the flags cannot be kept in registers.
It also makes exception unwinding much harder to implement.

> Compared to the effort to implement exceptions in the first place,
> the extra effort required to get the lifetime of temporaries correct
> doesn't seem inordinate.

> For these reasons I believe "end of statement" (or more properly
> "end of outermost expression") is the best answer for lifetime
> of temporaries.

Since we are trying to establish which of several possible implementation
strategies is "correct," I think these last two paragraphs are a
circular argument.  My counterclaim:

Destroying temporaries at end of statement offers implementors a choice
between potentially exponential code growth and greatly increased
difficulty of implementing exception handling.  This dilemma exists only
to make it easier to handle expressions of a kind people write in practice
only very rarely.

For these reasons, I believe that temporaries created in a conditional
context should be destroyed in that context.
-- 
				--Andrew Koenig
				  ark@europa.att.com