🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

6 total messages Started by Antony Hodgson Fri, 31 Aug 1990 23:49
Lack of distinction between input & output fn parameters
#465
Author: Antony Hodgson
Date: Fri, 31 Aug 1990 23:49
37 lines
2130 bytes
I have often found myself writing functions in which there is one or
more "input" variable and more than one output (for example, a routine
which computes both the eigenvalues and corresponding eigenvectors of
a matrix or anything which returns a structure/object and an error
code).  Such functions have prototypes which look like the following:

	void EigenStuff( Matrix A, Vector EVals, Matrix EVectors )
or	errorcode SomeFunction( int i, Object X )

This syntax does not make clear which of the parameters in the 
prototypes are used as input values and which are return values.
I was thinking that a clearer syntax might be something like the
following:

	void (Vector Evals, Matrix EVectors) EigenStuff( Matrix A )
and	errorcode (Object X) SomeFunction( int i )

and the functions could be used as follows:

	( EVals, EVectors ) = EigenStuff( A )
and	if ( (X) = SomeFunction(i) == BAD_NEWS ) ...

This syntax makes clear which parameters are required as input and 
which are computed and returned by the function.  It also is fully 
compatible with existing code.  There may be some problem with variables
which are passed by reference since they can be both input and output,
but even so, this syntax might be clearer:

	errorcode ( Matrix &A ) MatrixInverse( Matrix &A )
used as:  if ( (A) = MatrixInverse(A) == NON_SINGULAR ) ...

Does anyone think this is a good idea, or is it simply, in the words
of one recent contributor, a minor convenience but not a solution to
a significant problem?  Your comments are appreciated.

Tony Hodgson	ahodgson@hstbme.mit.edu
Unnecessary copying of returned object
#466
Author: Antony Hodgson
Date: Fri, 31 Aug 1990 23:56
22 lines
1550 bytes
I'm a fairly recent user of C++, but I've already noticed one situation
in which a lot of unnecessary object creation occurs which I think could
be solved by a slight change in syntax.  This is the common situation in
which one creates a temporary object which is intended to be the returned
object, but since it is a local object, one must return a copy of it.
Two objects are therefore created when only one ought to be needed.

Consider the following:

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

Could an intelligent compiler bypass this copying without the help of
any new syntax?  Or, failing that, would it be reasonable to introduce
a new keyword such as 'returnvalue' which would be defined to have the
same type as the specified return value?  Any comments?

Tony Hodgson	ahodgson@hstbme.mit.edu
Re: Unnecessary copying of returned object
#473
Author: Bjarne Stroustrup
Date: Sat, 01 Sep 1990 13:09
19 lines
1024 bytes

Antony Hodgson @ Massachusetts Institute of Technology writes

 > Consider the following:
 > 
 > 	Vector Vector::operator + ( Vector & A )
 > 		{
 > 			Vector temp;
 > 			// for all valid i, temp[i] = (*this)[i] + A[i]
 > 			return temp;  // copy of temp made here
 > 		} // temp deallocated here
 > 
 > Could an intelligent compiler bypass this copying without the help of
 > any new syntax? 

Yes it could. The technique is described in the annotated C++ reference
manual in section 12.1.1c. I believe the technique is used in the Zortech
compiler (existence proof).
Re: Unnecessary copying of returned object
#474
Author: Andrew Koenig
Date: Sat, 01 Sep 1990 13:21
27 lines
1319 bytes
In article <1990Aug31.235606.166@athena.mit.edu>, ahodgson@hstbme.mit.edu (Antony Hodgson) writes:

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

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

Yes.

Moreover, I hear that at least one commercially available C++
implementation already does this.

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

The language definition permits this optimization.
-- 
				--Andrew Koenig
				  ark@europa.att.com
Re: Unnecessary copying of returned object
#483
Author: 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
Re: Unnecessary copying of returned object
#486
Author: Piercarlo Grandi
Date: Thu, 06 Sep 1990 16:13
53 lines
3728 bytes
On 4 Sep 90 21:18:59 GMT, I wrote, as an aside to a technical discussion:

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

This seems to have caused offense. I want to state that it was not meant
as other than irony, which I hope was understood. Apologies to any party
that felt this ironic paragraph was serious.

	Another aside on AT&T and standards: somebody once remarked that
	the SVID and its verification suite were designed in places so
	that apparently one *must* copy the AT&T implementation to pass
	it; for example, where multiple error codes could conceivably
	be returned, the SVID or its verification suite would accept as
	conforming only the code returned by System V, thus forcing
	other implementations to perform certain tests in the same order
	as the System V one. This was suspected to be a ploy to defeat
	cloners, and not sloppyness on the part of the authors of the
	SVID or its verification suite. It happened that eventually in
	parts the System V implementation evolved, other codes were
	returned, and thus *System V would fail to be certified as SVID
	conforming*. Now, this shows that probably, like in all large
	organizations, the left hand does not know what the right hand
	is doing, and this is often a more credible explanation than
	conspiracy theories. However the story has a moral: those who
	did not believe that AT&T had just been sloppy took issue from
	this, and founded the OSF, to ensure an "open process", not
	just an "open specification", which they believed could be
	tweaked. This is the one point on which the fact that now C++
	is going to be ANSIfied is a win -- I would otherwise be
	confident that Stroustrup and his colleagues would do a better
	job, but (in the eyes of the conspiracy theorists) an "open
	process" is better, even if it leads to design-by-committee.

The point of the irony was to (as is usual for me) show the dangers of
complexity; with any work that is complicated enough and still evolving,
even the organization to which its designer belongs has difficulty
keeping up with it. There is no need to invoke conspiracy theories,
except to make irony.

I hope (against all past experience) that the ANSIfication, which after
all benefits from the work of Stroustrup, Shopiro, etc..., as well as
many others, will make the language ever *simpler*, and thus ever more
accessible, to any user and any implementor, including AT&T's :-).
--
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
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads