Path: utzoo!mnetor!uunet!husc6!mit-eddie!uw-beaver!teknowledge-vaxc!sri-unix!quintus!ok
From: ok@quintus.UUCP (Richard A. O'Keefe)
Newsgroups: comp.lang.c
Subject: Re: `noalias' vs `register'
Message-ID: <475@cresswell.quintus.UUCP>
Date: 17 Dec 87 02:13:42 GMT
References: <6829@brl-smoke.ARPA> <9753@mimsy.UUCP> <6830@brl-smoke.ARPA> <6845@brl-smoke.ARPA>
Organization: Quintus Computer Systems, Mountain View, CA
Lines: 69
Summary: please clarify

In article <6845@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes:
> 	register thing *p;	/* p is possibly in a register */
> and
> 	noalias thing *p;	/* (*p), not p, is unaliased */
> Consider adding to your choice of the above the following code:
> 	*p = 1;
> 	{	/* should be a function, shown in-line for simplicity */
> 	thing *q = (thing *)p;	/* cast necessary if noalias */
> 	*q = 0;
> 	}
> 	if ( *p )
> 		;	/* noalias is allowed to get here */
> 	else
> 		;	/* register always gets here */
> See the difference?
> (I actually oversimplified the example.  Don't take it too literally.)
> 
I don't understand this.  In Doug Gwyn's example, *p HAS AN ALIAS!
That is, there are two ways (*p and *q) of getting at the same
location.  If this isn't illegal, what is the point of 'noalias'?

This is definitely the wrong time to put 'noalias' in.
The Committee have apparently rejected a number of otherwise sensible
things on the grounds of "no prior art".  This one they should reject
because there IS prior art, and it turned out to be a bad idea.

Remember PL/I?  That was an incredibly complicated language that IBM
used to sell.  I believe some museum pieces still run it.  You used
to be able to say things like

	DECLARE FRED ENTRY(BINARY FLOAT) RETURNS(BINARY FLOAT)
		REDUCIBLE;
	DECLARE JIM BINARY FIXED PRECISION(15,0)
		ABNORMAL;

What the first of these declarations meant was that if the
compiler saw	FRED(X) + FRED(X)  it was entitled to compile
it as FRED(X)*2.0, whereas if you said
	DECLARE FRED .... IRREDUCIBLE;
it was obliged to produce two procedure calls.

What the second of these declarations meant was that the
compiler was entitled to assume that nobody would change JIM
behind its back, so that if for example it saw JIM+JIM it
was entitled to compile it as JIM*2.  The PL/I manual I just
checked explicitly says "If B is ABNORMAL, the expression B+B
is not necessarily equivalent to the expression 2*B."

One problem with this is that if a variable can change behind
the compiler's back, it isn't just the compiler that gets
confused.  If B is ABNORMAL, what *is* the expression B+B
equivalent to?  But the main trouble with it was that you could
lie to the compiler, quite inadvertently.  It was an explicit
feature of PL/I that it wasn't supposed to protect the
programmer from himself, and my word, that was one feature you
you could be sure of.

Please, if something like 'noalias' is added to C, define it so
that it is provably easy for a simple compiler to determine when
the program is inconsistent with the declaration.

Anyway, why are the Committee only doing half a job?  What's the
point of introducing NORMAL (the default being ABNORMAL) without
introducing REDUCIBLE (the default being IRREDUCIBLE)?  Having
the C compiler recognise that sin(x) or strlen(s) only needs to
be evaluated more than once in some complicated expression would
be more useful to me than making promises about pointers that
the compiler isn't apparently expected to check, and the 'noalias'
attribute on the arguments is not enough to allow that optimisation.