[comp.lang.c] some objections to 'noalias'

ok@quintus.UUCP (Richard A. O'Keefe) (12/21/87)

'register' is a promise to the compiler: "I faithfully promise
	not to take the address of this, and if that helps you,
	fine."  This is something the compiler can verify, and
	if you break your promise the compiler can and should
	warn you.

'const' is a promise to the compiler: "I faithfully promise
	not to store through THIS path, and if that helps you,
	fine."  This is something the compiler can verify, and
	if you break your promise the compiler can and should
	warn you.  This is a positive help to programmers, as
	if you don't intend to change a parameter, you should
	declare it const, and the compiler will warn you about
	a mistaken change (the only known way of catching the
	writing-"="-instead-of-"==" bug).
	
'volatile' is a warning to the compiler: "watch out, this thing
	may change at any time".  The compiler cannot verify
	this, but it is safe for the compiler to believe you;
	the worst that can happen is loss of speed.

'noalias', however, is a promise to the compiler which the
	compiler cannot check, which it is NOT safe for the
	compiler to take on faith.

So we have two problems with "noalias"
(1) "noalias" does NOT mean "no alias", as Doug Gwyn showed in
    an example.  It means something like "there may be any number of
    aliases for this thing, one of which has the noalias property,
    and some of which, due to casting, have not, but changes will
    only be done through the version having the noalias property,
    so the compiler may rely on that version not changing
    unexpectedly."  Whatever the exact rule is, it is something
    quite different from and more complex than a simple "no aliases"
    rule, so the name is misleading.

(2) Believing the programmer is not a safe approximation.
    Judging from some of the examples so far, the intended property
    may not be computable.

Having some way of telling a compiler that something has no aliases
sounds like a really good idea.  (Euclid did this by making all
aliasing illegal.  One of the reasons for having storage pools
explicit in that language was so that a compiler could tell that
two pointers to different pools couldn't possibly be aliases.)  But
the right way to do this is to come up with some property which the
compiler (or a separate checker) can verify, and which implies the
property of interest.  This is a non-trivial task in language
design, especially in the case of C.  Rushing it in at the last
minute is not a good idea.

(3) A snag with things like volatile and noalias is that they
clutter up the language.  There are a great many things that one
might want to tell a compiler.  There should be one generic
mechanism for all of them.  The simplest scheme I can think of
is to replace the rule

	type_qualifier : CONST | VOLATILE ;

by	type_qualifier : CONST | PRAGMA '(' praginfo ')' ;

	praginfo : /* empty */ | praginfo primary_expr ;

so that one could declare
	extern pragma(volatile)
	struct device tty_device;
or
	static pragma(signal_handler)
	void my_sigfpe_handler(...) { ... }

or whatever.  The definition of 'praginfo' was carefully designed
so that
	#define pragma(x)
could be used in a compiler which didn't yet understand pragma(),
but in general a compiler would accept some pragmas and warn about
the others.  This approach takes one reserved word in the language,
but imposes no bound on the number of hints you can give the compiler.

If the FORTRAN committee have not found a need to introduce a 'noalias'
mechanism into that language (aliasing is quite possible in FORTRAN),
what makes C so special?  I have seen the February '87 draft of the
FORTRAN 8X (they'd better hurry) standard.  That's getting to be a
very complicated language indeed (user-defined types, with parameters
yet!) but they still hadn't put 'noalias' in.

The approach taken by the majority of other programming languages is
that if you change one alias of a location and then access it via
another location it's your own silly fault if you don't get the
answer you expected.  I can't think of any of my own C programs
where it would not have been appropriate to declare ALL variables
'noalias'.  So that's a fourth problem with noalias: it's back to front.

Why not simply say that the compiler is entitled to assume 'noalias'
for everything, and that if the programmer wants unsafe aliases s/he
should declare the variables in question to be 'volatile'?  Doesn't
"volatile" mean that a variable may change behind the compiler's
back, and isn't that exactly what we want here?

This might perhaps be a "Quiet Change", but nobody ever told me that
aliasing was supposed to be legal in C, so even that isn't clear.
I don't see why having noalias as the basic assumption should be any
more of a burden on me in C than it is in FORTRAN.

mmengel@cuuxb.ATT.COM (Marc W. Mengel) (12/23/87)

<>

In article <485@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes:
...
>'noalias', however, is a promise to the compiler which the
>	compiler cannot check, which it is NOT safe for the
>	compiler to take on faith.
>
Actually, I thought the whole point was to put noalias in simply because
the compiler cannot check it...  That is, there are optimizations possible
if you know that a pointer isn't aliased, and the only person who can
possibly tell this for real is the programmer.  Now you tell me the
compiler cannot "safely" take this "on faith".  Well, the compler can't
"safely" take pointer casts like converting a (char *) to a (float *)
"safely", after all, there could be allignment problems.  A C compiler
*has* to take things like noalias and pointer casts on faith because
there is *not* any way to check for them in the language.

>So we have two problems with "noalias"
>(1) "noalias" does NOT mean "no alias", as Doug Gwyn showed in
>    an example.  It means something like "there may be any number of
>    aliases for this thing, one of which has the noalias property,
>    and some of which, due to casting, have not, but changes will
>    only be done through the version having the noalias property,
>    so the compiler may rely on that version not changing
>    unexpectedly."  Whatever the exact rule is, it is something
>    quite different from and more complex than a simple "no aliases"
>    rule, so the name is misleading.

Mark Twain used to say that "a man who doesn't read is no better off
than a man who can't read".  If there is another pointer to the location
pointed to by a "noalias" pointer that the programmer is certain can't 
end up being used in the scope of the "noalias" pointer, that means the 
programmer knows the optimizations are okay, and the programmer can *tell* 
the compiler he knows that they're okay.

>(2) Believing the programmer is not a safe approximation.
>    Judging from some of the examples so far, the intended property
>    may not be computable.

Right. It is NOT computable. Therfore you (the compiler) *have* to believe 
the programmer, since you can't figure it out yourself.

In C, we believe the programmer about a lot of things:
	Pointer casts
	Function arguments (pre ANSI,anyhow)
	Array Subscripts
	etc.
	etc.
All of a sudden you think we can't believe the programmer anymore.
>
>Having some way of telling a compiler that something has no aliases
>sounds like a really good idea.  (Euclid did this by making all
>aliasing illegal
...
>) But the right way to do this is to come up with some property which the
>compiler (or a separate checker) can verify, and which implies the
>property of interest.  This is a non-trivial task in language
>design, especially in the case of C.  Rushing it in at the last
>minute is not a good idea.
>
>(3) A snag with things like volatile and noalias is that they
>clutter up the language.  There are a great many things that one
>might want to tell a compiler.  There should be one generic
>mechanism for all of them.  The simplest scheme I can think of
>is to replace the rule
...[long discussion of how we should use pragmas for volatile, noalias, etc.]

volatile and noalias are built in to make them mandatory.

pragma is there to allow optional extensions.

>
>If the FORTRAN committee have not found a need to introduce a 'noalias'
>mechanism into that language (aliasing is quite possible in FORTRAN),
>what makes C so special?  I have seen the February '87 draft of the
>FORTRAN 8X (they'd better hurry) standard.  That's getting to be a
>very complicated language indeed (user-defined types, with parameters
>yet!) but they still hadn't put 'noalias' in.

Fortran uses copy-in copy-out address passing, and (in current
implementations) doesn't have an address-of operator. Therefore
aliasing is much less of a problem.  Take the classic example
of complex numbers:

typedef float complex[2];

mult( c1, c2, c3 )
	complex c1, c2, c3;
{
	c3[0] = c1[0] * c2[0] + c1[1] * c2[1];
	c3[1] = c1[1] * c2[0] + c1[1] * c2[0];
}
 
in C this leads to an incorrect complex multiply (by definition) if you 
call it as:

	complex c1, c2;
	...
	mult(c1,c2,c1);

This is due to "aliasing".  Fortran, since it uses copy-in, copy-out
argument passing, does not have this problem. (i.e. you get a correct
complex multiply implementing complex numbers with arrays this way, since
you deal with 3 copies, 2 of c1, one of c2, whose values are copied
back out at the end of the procedure.)

>The approach taken by the majority of other programming languages is
>that if you change one alias of a location and then access it via
>another location it's your own silly fault if you don't get the
>answer you expected.  I can't think of any of my own C programs
>where it would not have been appropriate to declare ALL variables
>'noalias'.  So that's a fourth problem with noalias: it's back to front.

The way C is defined, if p1==&a, and p2==&a, then *p1 == *p2 at any
given time.  This means the compiler is forced to always update 
the location at the end of a pointer, even when it would be more
efficient to hang onto it for a little while, and store it later:

	p1=&a;
	p2=&a;

	*p1 = b;
	*p1 &= 0xff;
	printf("%d\n",*p2);
	*p1 |= 0x100;

would be less code if we didn't have to have the right value for *p2.
The way C is defined, however, we *do* have to have the right value for
*p2 here.  "noalias" gives us a way to tell the compiler that its okay 
not to worry about keeping the memory location at *p1 always in sync, 
to keep that value of b&0xff around in a register until we compute
(b&0xff)|0x100, and then maybe get around to storing it in memory.

>Why not simply say that the compiler is entitled to assume 'noalias'
>for everything, and that if the programmer wants unsafe aliases s/he
>should declare the variables in question to be 'volatile'?  Doesn't
>"volatile" mean that a variable may change behind the compiler's
>back, and isn't that exactly what we want here?

Because it breaks existing code, like that above.
>
>This might perhaps be a "Quiet Change", but nobody ever told me that
>aliasing was supposed to be legal in C, so even that isn't clear.
>I don't see why having noalias as the basic assumption should be any
>more of a burden on me in C than it is in FORTRAN.

It is legal, entirely because of the way address of is defined in C.
Sure nobody told you it was "legal", nobody said it wasn't, and the
operators and syntax allow you to do it.  You just assumed it wasn't
because you have used languages which prohibit it.
-- 
 Marc Mengel	

 attmail!mmengel
 ...!{moss|lll-crg|mtune|ihnp4}!cuuxb!mmengel

ok@quintus.UUCP (Richard A. O'Keefe) (12/23/87)

In article <1453@cuuxb.ATT.COM>, mmengel@cuuxb.ATT.COM (Marc W. Mengel)
writes several times that
> Fortran uses copy-in copy-out address passing
and says onces that
> (in current implementations) doesn't have an address-of operator.
Several current implementations DO have an address-of operator, not
that it matters.
The statement that Fortran uses pass-by-value-return (anyone remember
Algol W?) is simply false.  >>Some Fortran implementations<< use
valret.  They are allowed to.  Some Fortran implementations use
pass-by-reference.  They are allowed to.  Two Fortran compilers I have
used pick different methods for different functions, depending on
optimisation level.  They are allowed to.  If someone writes a Fortran
subroutine
	SUBROUTINE CPXMPY(RA,IA, RB,IB, RC, IC)
	    REAL RA,IA, RB,IB, RC,IC
	    RC = RA*RB - IA*IB
	    IC = RA*IB + RB*IA
	    RETURN
	END
then he is in precisely the same sort of trouble as the C programmer
who writes the C function you exhibited.  If you
	    CALL CPXMPY(RA,IA, RB,IB, RA,IA)
then you are going to have trouble in some Fortran implementations, and
it is YOUR fault, not theirs.
In fact, just now I tried this with the f77 compiler on a SUN-3/50
running SunOS 3.2.  With optimisation off, it gives the "incorrect"
answers, due to using pass-by-reference.  But with optimisation on
(f77 -O foo.f), it gives the "correct" answers, because it is making
local copies.  BOTH behaviours are in conformance with the standard;
it is the >program< which is non-conforming, not the compiler.

I would claim that aliasing is a worse problem in Fortran than in
C.  For example, the option of having cpxmpy accept records and
return a record is not available in Fortran 77 (it IS available in
Fortran 8X), so there simply isn't any safe way to write this in
Fortran, while there is in C.

So my question: if people care about optimising Fortran (and they DO)
and they care about writing correct programs in Fortran (and they DO)
and if aliasing is a problem in Fortran (and I've just shown that it
IS), what is so special about C that it needs a 'noalias' declaration?
(By the way, there exist tools such as PFORT which can check that the
Fortran no-aliasing rules are not violated.  But then Fortran is a
much simpler language than C.)

The point that the C compiler already takes a great deal on blind
faith is quite right, and it takes a lot of the steam out of my
objections to 'noalias'.  But I think that explains the increasing
popularity of C interpreters (one that sounded impressive was just
announced on the net).  My experience has been that programs which
use casts a lot are significantly harder to debug than ones which
lint is happy with; has yours been any different?  Ok, so the boat
is leaky; is that any reason to bore more holes in it?

I should make it plain that my objection to 'noalias' was more vehement
than perhaps was warranted, because on the whole I am tremendously
impressed by the work of the ANSI C committee.  I am also watching the
British Standards Institute working group on Prolog; that is being done
in a most unprofessional fashion.  I have repeatedly begged them (given
that their mandate was to create a standard based on Edinburgh Prolog)
to do exactly that, and after some years they finally explicitly
rejected the idea.  They are busily inventing their own language.  After
watching that outfit bumble around, the ANSI C committee look amazingly
good.

    --	'nolias' still does not mean "no alias" so the >name< is bad
    --	it is still back-to-front
    --	if "other languages do it" was a good enough argument for
	giving parentheses more than merely grouping effect, then
	"other languages do it" is a good enough argument for
	having "noalias" be the default
    --	pragma(noalias) is still a better approach
	{what does #pragma do?  Surely a macro processor which may be
	completely separate from the compiler is the wrong place for
	such things?}
and Marc Mengel has not refuted these claims.

chris@mimsy.UUCP (Chris Torek) (12/23/87)

In article <1453@cuuxb.ATT.COM> mmengel@cuuxb.ATT.COM (Marc W. Mengel) writes:
>Fortran uses copy-in copy-out address passing....

Some FORTRAN compilers may indeed use copy-in/copy-out (I believe this
is usually called `value-result'), but I think it is not mandated.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

ksb@j.cc.purdue.edu (Kevin Braunsdorf) (12/24/87)

In article <492@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes:
>The statement that Fortran uses pass-by-value-return is simply false.
 .... Some Fortran implementations use valret. ....
 .... tools such as PFORT which can check that the aliasing ...
 .... Fortran no-aliasing rules are not violated ....
 .... But then Fortran is a much simpler language than C ....
 .... there simply isn't any safe way to write this in Fortran ....
 .... while there is in C.

FORTRAN?  Right: they chose *not* to deal with the aliasing issue by
waving their collective hands at it: "You can't do that!" they said!
Then the compiler should check for it: we are back to cc/lint with
f77 & pfort?  If it requires more info than the compiler has it is
not relevent to a compiler discussion.

Clearly.  Enough about FORTRAN: I could *not* care any less.  This
shows how C is *trying* to deal with a problem that FORTRAN and other
languages just gave up on... read on.

 .... what is so special about C that it needs a 'noalias' declaration?

The aliasing problems in C happen at "deeper" levels due to the
pointer to a pointer to a widgit constructs.  C is trying to cope with
the aliases rather than "forbid" them.

> The point that the C compiler already takes a great deal on blind
> faith is quite right, and it takes a lot of the steam out of my
> objections to 'noalias'.
> .... <and> casts <make code> significantly harder to debug ...

Yes: this hole has positive pressure behind it.  When trying to insert
a noalias assertion into the code a good programmer will prove to themself
that it is not true.  And we are still coping with the problem here.

> I should make it plain that my objection to 'noalias' was more vehement
> than perhaps was warranted, because on the whole I am tremendously
> impressed by the work of the ANSI C committee.
I am not:  recently they have begun to bag things.
(#pragma, (char *) == (void *), unary +, enum ~= int)

>    --	'noalias' still does not mean "no alias" so the >name< is bad
See [Below].

>    --	if "other languages do it" was a good enough argument for
>	giving parentheses more than merely grouping effect, then
>	"other languages do it" is a good enough argument for
>	having "noalias" be the default
I agree completely: the "other languages do it" was *never* good enough
for the (..) "feature".  C should re-a range expressions with impunity.
(I'd rather see the bag-on "unary +" for goodness sake!)

>    --	pragma(noalias) is still a better approach
>	{what does #pragma do?  Surely a macro processor which may be
>	completely separate from the compiler is the wrong place for
>	such things?}
Pragma is the largest BAG-ON I have ever seen in a compiler.  It can do
anything & nothing all at the same time.  (Stop it with the bags!)  This
noalias type modifier can *really* change the ADT (set of ops & data).

>and Marc Mengel has not refuted these claims.
OK, I will.  [Below] is here.

The "noalias" assertion *should* mean that there is no other *active*
handle on the data item.  It should also tell the compiler that if you
see me giving this handle to a function:
	a) you must sync the data
	b) compute the required handle	(could be address arith here)
	c) process function call
	d) mark any temps as invalid (based on this data); the subroutine
	   could have changed it, but we have control again (for now).

So basically:

diddle(pi)
exclusive int *pi;
{
	*pi = 0;			/* here we can move 0 to a temp */

	while (something()) {
		*pi += someexpr();	/* here we can use the temp	*/
	}
/* possible sync for *pi	*/

	g(*pi);				/* *pi in sync yet, use temp?	*/

/* forced sync point for *pi	*/

	f(pi);				/* we sync before the call	*/

/* force sync before we return	*/
}

You see how the compiler (even in a simple case) can make a register save
or no-save choice around the call to g()?  In more complex code *only* the
compiler is going to be able to keep track of all of the registers and
sync points involved.

The whole key to the "exclusive" access (Marc and I call it) restriction
is that the handle must be the only *active* handle; others may exist; but
they may not be in use  (even better is that a runtime checker *can* be
written for this. {Keep a back pointer to the active handle with the
data... really slow but it will find the bugs. And changes the ADT}).
Just like checking array bounds, right?

Marc has already pointed out the the compiler believes the programmer about
pointer casts, pointer references (through nil), array bounds, parameter
prototypes (pre-ANSI).

What about memory allocation:
	pi = (int *) malloc(sizeof(char));
	      ^^^^^ 		   ^^^^
or deallocation:
	free(& BagMe);		/* for a good time		*/
	free(main);		/* for a core dump		*/
or any of a number of other very important semantic restrictions?

A C programmer cannot code without thinking of all of these.  This
feature makes one more aspect of the programmers job clear (alias control).



Finally:  I do not feel the feature belongs in ANSI C.  It is not C.
It is too late to add it.  It is a bag-on addition.  It is a poor
choice of keywords.  And for all the good it could do it will cause
more harm to add it this late in the game.

Wait for D or K.

Kevin Braunsdorf	ksb@j.cc.purdue.edu
K Project		pur-ee!gawk!klang

roger@celtics.UUCP (Roger B.A. Klorese) (12/29/87)

In article <492@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes:
>I would claim that aliasing is a worse problem in Fortran than in C.

Probably true.

>So my question: if people care about optimising Fortran (and they DO)
>and they care about writing correct programs in Fortran (and they DO)
>and if aliasing is a problem in Fortran (and I've just shown that it
>IS), what is so special about C that it needs a 'noalias' declaration?

Because many people have *already* extended their FORTRAN compilers
to handle aliasing properly.  Quoting from the Celerity Computing
Tools and Applications Reference Manual, Volume III, Book 2 (Languages,
Kernel), which is Copyright 1986 Celerity Computing, on page 1-14:

"However, even programs that contain hidden aliasing can be safely
optimized if the optimization control '-Oc s' is specified.  It causes
the optimizer to refrain from placing in registers any expressions
that depend on common-block variables or incoming parameters."

When parameters and common block allocations are eliminated from
consideration, and proper subscripting is observed, FORTRAN aliases
should all be detectable.  (Any cases left out?)
-- 
 ///==\\   (Your message here...)
///        Roger B.A. Klorese, CELERITY (Northeast Area)
\\\        40 Speen St., Framingham, MA 01701  +1 617 872-1552
 \\\==//   celtics!roger@necntc.nec.com - necntc!celtics!roger

gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/06/88)

In article <485@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes:
-If the FORTRAN committee have not found a need to introduce a 'noalias'
-mechanism into that language (aliasing is quite possible in FORTRAN),
-what makes C so special?

Pointers!

-Why not simply say that the compiler is entitled to assume 'noalias'
-for everything, and that if the programmer wants unsafe aliases s/he
-should declare the variables in question to be 'volatile'?

The existing (K&R) C language does not permit the "noalias" property
(i.e. hyperoptimization) to be the default.

gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/06/88)

In article <1453@cuuxb.ATT.COM> mmengel@cuuxb.UUCP (Marc W. Mengel) writes:
>Right. It is NOT computable. Therfore you (the compiler) *have* to believe 
>the programmer, since you can't figure it out yourself.

That is the key philosophical point about specifying "noalias".
If it were just like the other type qualifiers, it wouldn't have
been invented.  As a matter of fact, it arose as the resolution
of an attempt to overload the semantics of one of the other type
qualifiers ("const").

P.S.  Good article, Marc!

mmengel@cuuxb.ATT.COM (Marc W. Mengel) (01/06/88)

In article <492@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes:
>In article <1453@cuuxb.ATT.COM>, mmengel@cuuxb.ATT.COM (Marc W. Mengel)
[several corrections of my limited experience with FORTRAN]
	I was intending to give an example of aliasing
	caused by call-by-reference argument passing, and
	how it can lead to different results from essentially
	identical code.   All of the FORTRANs I have used use
	call by copy-in copy-out.  I never considered versions
	of f77 I have worked with ( the one from V7 unix, which 
	was kinda broken ) correct FORTRAN implementations, this
	should not neccesarily reflect on SUN's f77, which I have
	never used.

>I would claim that aliasing is a worse problem in Fortran than in
>C.  For example, the option of having cpxmpy accept records and
>return a record is not available in Fortran 77 (it IS available in
>Fortran 8X), so there simply isn't any safe way to write this in
>Fortran, while there is in C.

Aliasing is not a problem at all in the current C implementations.
There does not exist the call by reference/copy-in-copy-out
ambiguity, since all calls are by value, and explicit call
by reference can only be done using the address-of operator.
I never claimed that it was.  The problem is that the neccesity
of avoiding aliasing by always updating values at the end of
pointers (the way C currently behaves in all cases) is expensive,
and it would be useful to be able to tell the compiler that
it was "okay" to not do this updating in some cases.

>So my question: if people care about optimising Fortran (and they DO)
>and they care about writing correct programs in Fortran (and they DO)
>and if aliasing is a problem in Fortran (and I've just shown that it
>IS), what is so special about C that it needs a 'noalias' declaration?
>(By the way, there exist tools such as PFORT which can check that the
>Fortran no-aliasing rules are not violated.  But then Fortran is a
>much simpler language than C.)

Aliasing is not a problem in C. Ensuring that it is not a problem is
expensive.  People want to be able to turn off this expensive behavior
in specific cases where they know that it won't make a difference.

>The point that the C compiler already takes a great deal on blind
>faith is quite right, and it takes a lot of the steam out of my
>objections to 'noalias'.  But I think that explains the increasing
>popularity of C interpreters (one that sounded impressive was just
>announced on the net).  My experience has been that programs which
>use casts a lot are significantly harder to debug than ones which
>lint is happy with; has yours been any different?  Ok, so the boat
>is leaky; is that any reason to bore more holes in it?

lint is often perfectly happy with type casts; explicit casts are
often useful.  Programs that lint doesn't like are often buggy.
Your argument is really that we shouldn't give C programmers another
way to "shoot themselves in the foot."

[ discussion of how ANSI is nonetheless doing a far better job
than other standards orginizations]
>    --	'nolias' still does not mean "no alias" so the >name< is bad

I agree a better name would be nice, alas I haven't thought of one.
Have you?

>    --	it is still back-to-front
>    --	if "other languages do it" was a good enough argument for
>	giving parentheses more than merely grouping effect, then
>	"other languages do it" is a good enough argument for
>	having "noalias" be the default
	
	not regrouping parenthesis is legal in all current C definitions.

	assuming pointer references won't be aliased is not legal in
	any C spec I've seen.

	thats a big difference in my book.

>    --	pragma(noalias) is still a better approach
>	{what does #pragma do?  Surely a macro processor which may be
>	completely separate from the compiler is the wrong place for
>	such things?}

pragma(noalias) and pragma(const) and pragma(volatile) are functionally
equivalent to having keywords, the only difference is that in one case
we are creating more keywords (and we still have undefined ones like
"entry" lying around...).  We have a conflict between more keywords
or longer definitions.  A trade-off. ANSI chose keywords, I don't think
it makes a whole lot of difference either way.

>and Marc Mengel has not refuted these claims.

I still haven't refuted two of them, nor do I care to.  I do maintain
that 
	1) C currently assumes that pointers can point anywhere, and
	   therefore updates memory at the end of pointer references
	   before using other non-register variables on the assumption 
	   that the pointer may point to those variables.
	2) Changing this behavior in general will break many existing
	   programs which intentionally use aliasing.
	3) The optizations possible when the compiler knows
	   pointer references are not aliased are signifigant.

and that this means we need a noalias-type solution.  The people who
care whether it looks like:

	noalias int *pi;

versus

	pragma(noalias) int *pi;

can decide which they like better, it makes no difference to me whatsoever.
-- 
 Marc Mengel	

 attmail!mmengel
 ...!{moss|lll-crg|mtune|ihnp4}!cuuxb!mmengel

gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/07/88)

In article <1469@cuuxb.ATT.COM> mmengel@cuuxb.UUCP (Marc W. Mengel) writes:

>	Aliasing is not a problem in C. Ensuring that it is not a problem is
>	expensive.  People want to be able to turn off this expensive behavior
>	in specific cases where they know that it won't make a difference.

(This is such a beautiful statement of what "noalias" is all about that
I wanted to make sure everyone noticed it.  Please excuse the reposting.)

ray@micomvax.UUCP (Ray Dunn) (01/08/88)

In article <9934@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
>In article <1453@cuuxb.ATT.COM> mmengel@cuuxb.ATT.COM (Marc W. Mengel) writes:
>>Fortran uses copy-in copy-out address passing....
>
>Some FORTRAN compilers may indeed use copy-in/copy-out (I believe this
>is usually called `value-result'), but I think it is not mandated.
>--                                       ^^^^^^

Chris!  This is VERY unlike you!

You reply to a VERY descriptive, VERY well written posting which clears up
MUCH of the confusion on the meaning/impact of the aliasing question, by a
nit-picking criticism of a point irrelevant to the central theme the poster
was expounding, and OF WHICH YOU ARE NOT EVEN SURE OF THE CORRECTNESS!!

I should, of course, have passed this (small) flame privately.  Forgive me,
but I wanted anyway to publicly thank Mark Wendel for his posting.

It was clear and very informative.  Bravo!

Ray Dunn.   ..philabs!micomvax!ray

ok@quintus.UUCP (Richard A. O'Keefe) (01/08/88)

In article <6971@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes:
> In article <1469@cuuxb.ATT.COM> mmengel@cuuxb.UUCP (Marc W. Mengel) writes:
> 
> >	Aliasing is not a problem in C. Ensuring that it is not a problem is
> >	expensive.  People want to be able to turn off this expensive behavior
> >	in specific cases where they know that it won't make a difference.
> 
> (This is such a beautiful statement of what "noalias" is all about that
> I wanted to make sure everyone noticed it.  Please excuse the reposting.)

This is such a CONFUSING statement that I too want to make sure everyone
notices it.  Is he talking about the compile-time cost of checking whether
something is aliased or not, or about the usually small run-time cost of
picking up another copy of something from memory just in case it was
aliased?  [If someone has an example of a real program where adding 'noalias'
to fewer than 10% of the variables makes a factor of 2 difference to run
time, let's see it!]  If whatever-it-is is so expensive, shouldn't the
cheap version be the default (as it is in Fortran, Pascal, COBOL, ADA,
BASIC, Euclid, and so on) and the expensive version be the one you have
to say explicitly?

    What we need at this point is a CLEAR description of exactly what
    the difference is between
	volatile int x;
		 int x;
	noalias  int x;
Are they points on a scale:
	volatile:	may change at any time
	{plain}:	may change in any *procedure call*
	noalias:	may only change by explicit assignment
If I say
	cat >>foo.h <<'EOF'
	extern noalias int x;
	extern void set_x(int i);
	EOF
	cat >>foo.c <<'EOF'
	noalias int x;

	void set_x(int i) { x = i; }
	EOF
	cat >>main.c <<'EOF'
	#include <stdio.h>
	#include "foo.h"
	main() {
	    x = 0;
	    set_x(1);
	    printf("x = %d\n", x);
	}
	EOF
	cc main.c foo.c
	a.out
is the output
	x = 0
legal?  {Presumably such a program is non-conforming, but is a conforming
compiler allowed to do this to it?}

mmengel@cuuxb.ATT.COM (Marc W. Mengel) (01/13/88)

In article <512@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes:
>In article <6971@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes:
>> In article <1469@cuuxb.ATT.COM> mmengel@cuuxb.UUCP (Marc W. Mengel) writes:
>> 
>> >	Aliasing is not a problem in C. Ensuring that it is not a problem is
>> >	expensive.  People want to be able to turn off this expensive behavior
>> >	in specific cases where they know that it won't make a difference.
>> 
>> (This is such a beautiful statement of what "noalias" is all about that
>> I wanted to make sure everyone noticed it.  Please excuse the reposting.)
>
>This is such a CONFUSING statement that I too want to make sure everyone
>notices it.  Is he talking about the compile-time cost of checking whether
>something is aliased or not, or about the usually small run-time cost of
>picking up another copy of something from memory just in case it was
>aliased?  

Actually, I was referring to BOTH sets of costs -- run time and compile
time; at compile time there are lots of headaches about synchronizing
whats in registers with whats in memory every time code for a pointer 
indirection is generated; and at run time, the cost of performing
the "usually small" costs of picking up another copy of something from
memory can add up quite a bit.

>[If someone has an example of a real program where adding 'noalias'
>to fewer than 10% of the variables makes a factor of 2 difference to run
>time, let's see it!]  If whatever-it-is is so expensive, shouldn't the
>cheap version be the default (as it is in Fortran, Pascal, COBOL, ADA,
>BASIC, Euclid, and so on) and the expensive version be the one you have
>to say explicitly?

Lets say I agree with you on your assumption that the best I can
get with noalias is a factor of 2 difference in run time... are you
claiming that optimizations that halve my run time are not worth
putting in???  Next, lets look at a nice piece of code...

vecadd( v1, v2, v3 , n)
	noalias int *v1, *v2, *v3;
	int n;
{
	register int i;

	for( i = 0; i < n ; i++, v1++, v2++, v3++  ){
		*v3 = *v2 + *v1;
	}
}

On certain machines like CDC Cyber 205's or other vector processors,
I could encode this as 1 instruction *if* i know that my 3 vectors
don't overlap.  noalias is the only way to efficiently tell the 
compiler this. (you may note in this example the compiler could
generate code that tests for vector overlap and branch to do either the
single vector instruction or the loop, in practice the logic needed
to make that kind of decision in the general case is arbitrarily complex
and may involve solving the (insoluble) halting problem...)

The noalias==cheap-version as a default will break existing code 
so that is *not* an option.

>    What we need at this point is a CLEAR description of exactly what
>    the difference is between
>	volatile int x;
>		 int x;
>	noalias  int x;
>Are they points on a scale:
>	volatile:	may change at any time
Right...

>	{plain}:	may change in any *procedure call*
or through *any* pointer indirection if the plain item  is not a 
register variable and the address of it is taken *anywhere*...  
It can only change in procedure calls that indirect pointers or 
use it directly (if it's global), if your compiler wants to keep 
that kind of bookkeeping, you can restrict your statement about 
procedure calls more.

>	noalias:	may only change by explicit assignment
right.

>If I say
>	cat >>foo.h <<'EOF'
>	extern noalias int x;
>	extern void set_x(int i);
>	EOF
>	cat >>foo.c <<'EOF'
>	noalias int x;
>
>	void set_x(int i) { x = i; }
>	EOF
>	cat >>main.c <<'EOF'
>	#include <stdio.h>
>	#include "foo.h"
>	main() {
>	    x = 0;
>	    set_x(1);
>	    printf("x = %d\n", x);
>	}
>	EOF
>	cc main.c foo.c
>	a.out
>is the output
>	x = 0
>legal?  {Presumably such a program is non-conforming, but is a conforming
>compiler allowed to do this to it?}

I don't see any aliasing in the code you have written...  The global
variable x is everywhere refered to as x, this causes no problems of
any sort that I can see, noalias or not.  The program you list will
output "x = 1\n" on stdout.

It sounds like you misunderstand what aliasing is, and hence miss seeing
when noalias would allow a valuable optimaztion...
-- 
 Marc Mengel	

 attmail!mmengel
 ...!{moss|lll-crg|mtune|ihnp4}!cuuxb!mmengel