🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c++
Article #483

Re: Unnecessary copying of returned object

#483
From: Piercarlo Grandi
Date: Tue, 04 Sep 1990 21:18
100 lines
5418 bytes
On 1 Sep 90 13:21:56 GMT, ark@alice.UUCP (Andrew Koenig) said:

ark> In article <1990Aug31.235606.166@athena.mit.edu>,
ark> ahodgson@hstbme.mit.edu (Antony Hodgson) writes:

ahodgson> Vector Vector::operator + ( Vector & A )
ahodgson> 	{
ahodgson> 		Vector temp;
ahodgson> 		// for all valid i, temp[i] = (*this)[i] + A[i]
ahodgson> 		return temp;  // copy of temp made here
ahodgson> 	} // temp deallocated here

ahodgson> Could an intelligent compiler bypass this copying without the
ahodgson> help of any new syntax?

ark> Yes.

Yes indeed, at the expense of a substantial bloat in space and time for
the compilation:

ark> One fairly easy to express such an optimization would be to say
ark> that `if every return statement in a function returns the same
ark> local variable, and that local variable has the same type as the
ark> function's return value, then the compiler should alias the local
ark> variable to the return value.'

This is a very good example of the divide between people like me and
people who love compilers that take several hundred kilobytes of core.

A compiler can discover a large number of things by careful analysis of
the source; in this case, by doing two passes over each function it can
discover that it can alias a local variable to the return value slot on
the stack or wherever it is.

Now let me observe: what is the cost of telling the compiler beforehand?
virtually none. What is the cost of letting the compiler discover it?
large -- you have to make two passes over each function, and delay
generating real code until the second pass, while you build a full in
memory representation of the procedure in the first pass, in order to
check whether you can alias or not.

ark> The language definition permits this optimization.

But is does not permit doing without it; if you have the option of
telling the compiler explicitly, like in Gnu C++, and you do, it can
avoid doing any analysis, and if you do not, it could then switch to
'slow-and-big' mode (but should not IMNHO).

Consider my favourite example of wise language design: the 'register'
keyword is defined such that you cannot take the address of variables so
tagged. Why ever, when the compiler, by the end of the function, knows
whether you have taken the address of the variable or not, and can then
ignore the 'register' specification if so?

But simply because Classic C has been carefully designed so as to be
compilable with a simple one pass compiler that has no memory between
statements except for declarations (that is the reason for 'register'
itself -- the compiler can allocate a register to hold a variable
between statements, without ever analyzing more than one statement at a
time, because you told it by a declaration that it would be worthwhile).

Note that Classic C does not actually *forbid* more sophisticated
compilation strategies; it makes it possible for a simple compiler to
compete with a sophisticated one, thanks to some assistance from the
programmer; if such assistance is not forthcoming, the compiler *can* do
more work (but should not IMNHO).

In C++ the trend is towards making it difficult for simple compilers to
be competitive with complicated (and theref ore unreliable) ones.

	What is more worrying is that C++ seems to be evolving also
	towards requiring ever more complicated *implementation*
	strategies as well; consider constructors/destructors and
	virtuals, and more recently and ominously, virtual base
	classes, and in the future, templates.

Consider the incredible syntax ambiguities (that could be easily
removed, with virtually 100% backwards compatibility), the complexity of
many rules, the fact that because of a single (IMNHO very unwise and
confusing) rule a single pass compiler is actually *impossible*, and
many other details.

	Did AT&T want to make it very difficult for anybody but
	themselves produce a conforming implementation? Or at least
	to make it so difficult to understand what a conforming
	implementation is so that people would stick by AT&T's for
	fear of the unknown? If this has been true, it has failed;
	it is well known that cfront is not conforming itself, i.e.
	AT&T have shot themselves in the foot :-).

A plea: remove the damn rule that requires two pass compilation of class
definitions. I think that it is damn unwise, and if people want to use a
class member in a member function body that appears before its
declaration, they should be damned. They should avoid doing anything so
gross and unreadable. Encourage people to define member functions after
the class definition, not within it!
--
Piercarlo "Peter" Grandi           | ARPA: pcg%uk.ac.aber.cs@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth        | UUCP: ...!mcsun!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk
Technical Details
Message-ID: <PCG.90Sep4221859@athene.cs.aber.ac.uk>
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!mcsun!ukc!dcl-cs!aber-cs!athene!pcg
References: <1990Aug31.234937.29938@athena.mit.edu> <1990Aug31.235606.166@athena.mit.edu> <11267@alice.UUCP>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!mcsun!ukc!dcl-cs!aber-cs!athene!pcg
From: pcg@cs.aber.ac.uk (Piercarlo Grandi)
Newsgroups: comp.std.c++
Subject: Re: Unnecessary copying of returned object
Message-ID: <PCG.90Sep4221859@athene.cs.aber.ac.uk>
Date: 4 Sep 90 21:18:59 GMT
References: <1990Aug31.234937.29938@athena.mit.edu>
 <1990Aug31.235606.166@athena.mit.edu> <11267@alice.UUCP>
Sender: pcg@aber-cs.UUCP
Organization: Coleg Prifysgol Cymru
Lines: 100
In-reply-to: ark@alice.UUCP's message of 1 Sep 90 13:21:56 GMT