confusion with char *a and char a[NUM]

Chris Torek chris at mimsy.umd.edu
Thu Dec 6 03:18:40 AEST 1990


In article <1990Dec4.214845.18949 at ccu.umanitoba.ca>
salomon at ccu.umanitoba.ca (Dan Salomon) writes:
>    char a[NUM];
>declares "a" to be a constant pointer to an array of char that points
>to the region allocated by the compiler.

One more time:
	a is not a constant pointer.
	a is an array.

How can you tell?
	sizeof((char *)0) is typically 2, 4, or 8.
	  ((char *)0 is a constant nil-pointer-to-char.)
	sizeof(a) is always exactly NUM.
 => conclusion: a is not a constant pointer to char.

How else can you tell?
	&3 is illegal (cannot take address of any rvalue, including
	  any constant).
	&a is a pointer (in ANSI C only, not in K&R-1 C) of type
	  (char (*)[NUM]).
 => conclusion: a is not a constant; it has an address.

How else can you tell?
	There are no other ways.  `a=b' and `a++' give the same sort of
	  error that `3=b' and `3++' produce.  If you do not understand
	  that arrays are not pointers, the declaration of `a' is not going
	  to help either.

>Hence you cannot change its value.

This conclusion is correct (see X3.159-1989; an array object, though an
lvalue, is not a modifiable lvalue), but for the wrong reason.

Note: the so-called `equivalence' between arrays and pointers is NOT
`array equals pointer'.  The rule is more complicated:

	In a value context, an object of type `array N of T' is
	transformed into a value of type `pointer to T' (discarding
	the constant N) by taking the address of the 0th element
	of that array.

Given:
	char *p, a[100];
	p = a;

this rule is applied as follows:

	<object, pointer to char, p>[object context] =
	  <object, array 100 of char, a>[value context];

The left hand side of the assignment statement is an object in an
object context, so nothing need be done.  The right hand side, however,
is an object in a value context.  For most objects (those that are
not arrays), the object is changed to a value simply by fetching its
current value.  This does not work for arrays since the `current value'
is (in this case) 100 `char's, which, back when Dennis Ritchie wrote
the first C compiler, was considered `too much work' to handle.  (So
were structure values; *that* has been rectified, but the array nuisance
has not.)  (Note: `too much work' is not just `on the part of the
compiler writer', but also `in terms of run-time code'.)  So the rule
above applies.  We have an `array N of T' (N=100, T=char), so we change
to a pointer to T by taking &array[0]:

	<object, pointer to char, p> =
	  <value, pointer to char, &a[0]>;

Now we have an assignment of the form `object = value;', so all that
is left is checking that the types match (they do) and doing the assignment.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris at cs.umd.edu	Path:	uunet!mimsy!chris



More information about the Comp.lang.c mailing list