Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!purdue!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!uakari.primate.wisc.edu!aplcen!haven!mimsy!chris From: chris@mimsy.umd.edu (Chris Torek) Newsgroups: comp.lang.c Subject: Re: "array" vs. "&array" ? Message-ID: <21726@mimsy.umd.edu> Date: 10 Jan 90 07:59:13 GMT References: <1989Dec22.013757.3086@sj.ate.slb.com> <571@mwtech.UUCP> <2378@ektools.UUCP> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 164 In article <21621@mimsy.umd.edu> I wrote more stuff about pointers and arrays being quite different, except in a few special cases. In article <2378@ektools.UUCP> randolph@ektools.UUCP (Gary L. Randolph) writes: >... the sentence in question is taken verbatim from Harbison and Steele, >pg 273, section 11.6.4. Since I do not have H&S (I should, if only for this sort of thing), I canot guess why they might have put in an `... or pointer to pointer to'. [me] >>There are a few special cases under which an object of type `array >>N of T' is converted to a value of type `pointer to T', and under which >>a declaration of type `array N of T' is converted to a declaration of >>type `pointer to T'. This does not make the types equivalent. They >>are not interchangeable. >Well, again I agree but then I am confused when I read, in K&R2, page >200 A7.1: > >If the type of an expression or subexpression is "array of T," for >some type T, then the value of the expression is a pointer to the >first object in the array, and the type of the expression is altered >to "pointer to T". This must be mentally applied to `places where lvalues (object designators) appear where values are desired'. For instance, given T arr[N]; when p = arr; appears, a value is desired, and the quoted sentence applies. >They do not say that the above is true only for a few special cases. It is an extremely common special case (values, i.e., expressions, appear everywhere). Nonetheless, it is a special case. >Based on experience, I agree with Chris, but then I am confused when >reading the above in two texts that I rarely question. >Is the quote from Harbison and Steele wrong? Not knowing the context, I canot say. >Am I wrong in the inference from K&R that: > >float arrf[3] = {1.2,2.3,3.4}; >arrf; /*evaluates to pointer to float according to K&R*/ >&arrf; /*evaluates to pointer to pointer to float (my inference)*/ Yes, this is wrong. `arrf', by itself, is in a value context: it is a statement which evaluates to the value of `arrf'. Thus, it undergoes the change from [value context] ; to [value context] ; `&arrf', however, consists of two parts. First there is a unary `&', and its argument is examined in *object* context. Here objects that are arrays are *not* converted. We have [value context] & [object context] ; and the `&' is applied to an object of type array 3 of float, yeilding a value (`&' produces values, not objects) of type `pointer to array 3 of float'. Since this is a value, nothing further happens. For comparison, when evaluating a = b; /* assume a and b are `int' */ I would write: [value context] ( [object context] a = [value context] b ) ; To evaluate the right hand side: [value context] and convert by the rule `an object that is not an array, when in value context, becomes a value by replacing the object with its current value'. (Classic C has some type extension rules here that New C defers until actually required.) So, if `b' has the value `42', we replace it with and now we have [value context] ( [object context] = ); Since we have an object on the left hand side, and an object context, we can do the assignment, setting `a' to 42. Now we have [value context] ( [result of assignment to a] ) The result of an assignment is the value you would get if you examined the assigned-to object: in this case the int-value 42, so it is a value in a value context and all is well. >Now I'm aware that if we look at a two dimensional array that if >int arr[2][3]; /*for example*/ >then it is quite different to say > >&arr evaluates to pointer to array of int >as opposed to >&arr evaluates to pointer to pointer to int (these are both wrong) >since, in the first case, arr++ would increment sizeof(arr) and in the >second case, arr++ would increment sizeof(pointer), which is not right. > >So how does page 200 of K&R apply here? Chris? In Classic C, `&arr' is, as always, an error. In New C, `&arr' produces a value of type `pointer to array 2 of array 3 of int'. Write it down (this time I will leave out the [context] notations): a. for `int (*p)[2][3]; p = &arr': p = & & takes object context, produces address of array as a value: p = `Evaluate' p: = The types match, so the assignment is correct. The object `p' is given the address of `arr'. `p++' adjusts p to skip over one whole `array 2 of array 3 of int'. On a byte-addressed machine, p++ adds 2*3*sizeof(int) to p. b. for `int (*q)[3]; q = arr;' q = This time the object is in a value context (rhs of `=') so the rule `object, array N of T, arr => value, pointer to T, &arr[0]' applies: q = Expand q: = The types match; q gets the given value. `q++' adjusts q to skip over one whole `array 3 of int'; on a byte-addressed machine, this adds 3*sizeof(int). -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris