[net.unix-wizards] C question

wje (06/22/82)

b
We have several Onyx systems here, and it is true that '&foo' is not
allowed for function or array names. This is, however, not a bug.
Onyx uses the PCC compiler, which will not allow this construct, and
rightly so. Reference to the C book will show that an unsubscripted
array reference is equivalent to a pointer to that array. Therefore,
using '&foo' actually implies double indirection! For example,
	char foo[2];

	foo	=>	&(foo[0])
	&foo	=>	&(&(foo[0]))

The actual bug is in the v7 cc, which does not report this as an
error, but ignores it.

The function name issue is a little more complex. Just like arrays,
a function name BY ITSELF has no value; it is only a way to indirectly
compute other values. Therefore, analogous to the interpretation of
an array name by itself, which is the address of the data, a function
name by itself is taken to be the address of the 'data', or function
body. Note that neither array or function names may be used as LVALUES.

	-Bill Ezell
	 Software Innovations, Inc.
	 decvax!sii!wje
	 ittvax!sii!wje
	 harpo!sii!wje

Steve@sri-unix (07/01/82)

Date: 20 Jun 1982 21:34:51 EDT (Sunday)
Regarding the Onyx Z8000 C compiler's problems with extraneous
ampersands, I would not say that the compiler is broken, just that it is
unnecessarily strict.  "Standard C", i.e. the Ritchie PDP-11
compiler allows one to add ampersands before expressions which
don't really need them because in early UNIX code, one often found
constructs of the form:

/* in one file */
main()
{
	extern foo;

	func = &foo;
	(*func)();
}

/* in another file */
foo()
{
	/* blah blah */
}

In other words, in the main procedure, the subroutine foo was being treated
like an "extern int", and because of the PDP-11 architecture, there was no
problem.  This was very common in V6-vintage programs, though I seem to see
less of it these days.  I suspect the construct was allowed to continue
because of the hassle it would cause otherwise.

The same goes for arrays.  There is one peculiarity though (in the Ritchie
PDP-11 compiler--I have not verified the results for any others):

If one says,
int x[10];

both x and &x resolve to the same value, the address of the first
element of the array.  However, the implicit size of these pointer
objects is different:

x+1 points to the second element of the array (equiv. to &x[1])

&x + 1 points to the 1st memory location AFTER the end of x (i.e.,
1 is multiplied by the entire size of the array x).

So, in this case, x and &x don't really mean the same thing, though
they point to the same memory location!

Hope these tidbits shed a bit more light on the subject, though
I feel you've probably got a fair amount of editting to do.  Neither
construct is mentioned in the C reference manual, presumably the bible for all
those who didn't start with the Ritchie compiler.

Dan@sri-unix (07/01/82)

Date: 21 Jun 1982 10:33:28 EDT (Monday)
Actually, it isn't legal C, since according to the reference
manual the "&" operator can only be applied to Lvalues, and
neither arrays nor procedures are Lvalues (since they can't
appear on the left-hand side of an assignment statement).

It still seems like a really stupid thing for a compiler to do.

jim@RAND-UNIX@sri-unix (07/02/82)

Date: Wednesday, 23 Jun 1982 10:47-PDT
I don't think you can claim the compiler is broken because it doesn't
accept "&foo" as the address of the function or array "foo".  See page
115 of Kernighan and Ritchie: "... since they are known to be functions,
the & operator is not necessary, in the same way that it is not needed
before an array name."

However, a friendly compiler ought to accept it with the & as well, since
it's unambiguous, and even consistent with the rest of pointers (that's
personal opinion, not canon).