Path: utzoo!censor!geac!torsqnt!news-server.csri.toronto.edu!cs.utexas.edu!sun-barr!ames!haven!mimsy!chris From: chris@mimsy.umd.edu (Chris Torek) Newsgroups: comp.lang.c Subject: Re: confusion with char *a and char a[NUM] Message-ID: <28341@mimsy.umd.edu> Date: 5 Dec 90 16:18:40 GMT References: <7656@umd5.umd.edu> <1990Dec4.214845.18949@ccu.umanitoba.ca> Distribution: na Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 72 In article <1990Dec4.214845.18949@ccu.umanitoba.ca> salomon@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 context] = [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]: = ; 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@cs.umd.edu Path: uunet!mimsy!chris Brought to you by Super Global Mega Corp .com