From: fjh@mundil.cs.mu.OZ.AU (Fergus James HENDERSON)
Subject: Re: Proposal: auto T&
Organization: Computer Science, University of Melbourne, Australia
Date: Wed, 26 Aug 1992 12:40:01 GMT

jamshid@ut-emx.uucp (Jamshid Afshar) writes:

>In article <2A991ABB.477D@tct.com> chip@tct.com (Chip Salzenberg) writes:
>>According to eric@tfs.com (Eric Smith):
>>>The "auto" in the function return value type tells the compiler to allocate
>>>the space for that automatic in the stack frame of the caller, instead of
>>>the stack frame of the called function.
>>
>>There is prior art.  GCC and G++ already allow named return values ...
>
>But is there current reason?  Can named return values let compilers do
>anything that they cannot do with a little bit of optimization (ARM 12
>Commentary)?

Yes, named return values allows a function to construct the return
value at the start of the function instead of just before actually
returning it.

You can also use auxiliary inline functions in combination with named
return values to effectively construct the return value at any point in 
the middle of the function, but this is very messy.

The reason for wanting to be able to construct the return value anywhere
in the function is to avoid having to introduce a temporary to hold
the return value, since the additional copying and destruction can be
quite innefficient, especially if the objects concerned contain dynamically
allocated data.

I suggested that instead of introducing some new syntax for this, compilers
should be allowed to optimize away the named temporaries. Barry Margolin
pointed out that the ARM disallows that in most cases, and Thomas M.
Breuel replied:

>barmar@think.com (Barry Margolin) writes:
>
>   fjh@munta.cs.mu.OZ.AU (Fergus James HENDERSON) writes:
>   >Here again compilers should be smart enough to optimize away the both the
>   >unnamed temporary AND the named temporary "retval".
>   >I don't know whether the latter optimization is allowed by the ARM
>   >(I suspect not), but it SHOULD be.
>
>   It is in limited cases.  Sec. 3.5 of the ARM explicitly says, "nor may an
>   automatic named object of a class with a constructor or a destructor with
>   side effects be eliminated even if it appears to be unused."  In most
>   cases, I suspect compilers won't check for the "with side effects" (if the
>   constructor or destructor isn't inline, they generally can't), and some
>   compilers may not even check whether the class has a contructor or
>   destructor.
>
>Yes, and this rule is unlikely to change. People are using
>constructors/destructors not only for memory management but also as a
>form of UNWIND-PROTECT (e.g., create a window on block entry and make
>sure it gets destroyed on block exit, no matter what).

Maybe I wasn't specific enough about the optimization I wanted to allow.
The idea is that whenever an object is copied and then immediately 
destroyed, it amounts to moving the object. If possible, it would be
more efficient to construct the object at the right location in the first
place. Thus when you see a sequence of instructions like

	construct an X at location A
	...
	copy X from location A to B using the copy-constructor
	destroy X at location A using destructor

they could be replaced by

	construct an X at location B
	...

I was not simply proposing that any variable that is not used apart
from having it's constructor/destructor called should be eliminated.
Code such as
	{ window w(...); ... /* w not used */ ... }
would not be affected.  As you say, Thomas, that would prevent the
style of using constructors and destructors deliberately for their side
effects. On the contrary, I think that the optimization would SUPPORT
this style of programming, if only one could ensure that all compilers
applied it (an impossible task, to be sure :-).

For example, say I have code like the following:

	Window error_message_window(int x, int y, const char *message) {
	    Window the_window(x, y, "Error", ERROR_COLOURS);
	    the_window << message;
	    return the_window;
	}

Now the problem is that the "return the_window" statement has 
*undesireable* hidden effects, because it does not simply make the
return value available to the calling function, instead it does all
this copying and destruction behind the scenes, which causes my screen
to be refreshed 3 times instead of once.

In this particular case one solution is to make error_message_window
a derived class of window; however in general this may not be appropriate.

Perhaps my suggestion is not the right way to solve the problem, simply
because you can never guarantee that compilers will always apply the
optimization. However I don't think it would break anyone's code.
(If anyone has got an example of real code that would break, please post
it! If anyone thinks that it *would* break someones code, please
explain why!). I don't think that the GNU extension is general enough.
The advantage of my suggestion is that it does not require any 
extensions to the language.

The philosophy of C and C++ has long been that if you don't use
a feature, you shouldn't have to pay for it. If my code doesn't
depend on side-effects when moving an object from one location to
another during return statements, why should I have to pay the cost
of all the unnecessary copying and destruction?

-- 
Fergus Henderson             fjh@munta.cs.mu.OZ.AU      
This .signature virus is a self-referential statement that is true - but 
you will only be able to consistently believe it if you copy it to your own
.signature file!