[comp.lang.c] A question about noalias and parameters.

wesommer@athena.mit.edu (William E. Sommerfeld) (12/19/87)

A common use for passing pointers to functions is to provide a
location for the function to stash a return value, or to provide
something similar to VAR parameters in PASCAL or IN OUT parameters in
ADA; this is useful if a function is to ``return'' multiple return
values.

In (pre-noalias) C, if one passes the address of a variable to a
function, the compiler must assume that the variable must, from that
point on, always be found at that address, because the function could
have stashed the variable's address someplace where some other code
expected to get at it later.

Is giving a pointer parameter an attribute of ``noalias'' supposed to
tell the compiler that the function is _not_ going to stash a copy of
the parameter someplace where another function can get to it?

In other words, are the two programs here supposed to be equivalent?

program 1:

void func(char *p1, char *p2, char **r1, char **r2);

main()
{
	register char *v1, *v2, *v3, *v4;

	... some computations using v1, v2, v3, v4 ...

	{
		char *temp1 = v3;
		char *temp2 = v4;
		func(v1, v2, &temp1, &temp2);
		v3 = temp1;
		v4 = temp2;
	}
	... more computations using v1, v2, v3, v4 ...
}

program 2:

void func(char *p1, char *p2, noalias char **r1, noalias char **r2);

main()
{
	char *v1, *v2, *v3, *v4;

	... some computations using v1, v2, v3, v4 ...

	func(v1, v2, &v3, &v4);

	... more computations using v1, v2, v3, v4 ...
}

That is, could a compiler which does smart register allocation cause
v3 and v4 to live in registers except for the duration of the call to
func(), because it knows that other function calls will not be able to
modify the values of v3 and v4?

					Bill Sommerfeld
					MIT Project Athena
					wesommer@athena.mit.edu

gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/20/87)

In article <2063@bloom-beacon.MIT.EDU> wesommer@athena.mit.edu (William E. Sommerfeld) writes:
>In other words, are the two programs here supposed to be equivalent?

If I understand your intent correctly, I think the answer is Yes.
By the way, this is not the only, nor even the main, use for noalias.

Note that it is not usually the pointer itself being declared noalias,
but rather the data it can access.  If, for example, the function directly
modifies an extern datum that could be accessed via a pointer-to-noalias
parameter, that is indeed a violation of the "noalias" guarantee.  It is
not always possible to detect such a violation at compile time, and it is
unlikely that any implementation other than a "safe development" one would
try to detect such violations at run time.

In the second program, The declaration of func() could have been
	void func(char *p1, char *p2, char *noalias *r1, char *noalias *r2);
which I believe is a closer match to the way you were thinking.  As it was,
the data pointed to by v3 and v4 was being guaranteed to have no alias,
which logically implies that v3 and v4 can also have no alias, but it
doesn't directly state that.

Basically, on the way into and out of a function, all buffered non-const
"noalias" data reachable via parameters must "be returned to their seats"
before the function starts and reloaded after the function returns.  That's
because the declaration promises that there are no aliases for the data,
so to keep from being surprised by what the code does in the function, the
promise has to be enforced across function boundaries.

I hope I explained this right.  It's hard doing from memory, without
having the final rules available at this time..