Path: utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!samsung!uakari.primate.wisc.edu!ark1!nems!mimsy!chris From: chris@mimsy.umd.edu (Chris Torek) Newsgroups: comp.lang.c Subject: Re: "array" vs. "&array" ? Message-ID: <21419@mimsy.umd.edu> Date: 23 Dec 89 16:22:41 GMT References: <1989Dec22.013757.3086@sj.ate.slb.com> <571@mwtech.UUCP> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 106 In article <571@mwtech.UUCP> martin@mwtech.UUCP (Martin Weitzel) writes: >Some days ago I posted a question if it is legal (or makes sense) >to write a "&" before an array. I received a few responses, some >mentioned, that an "&" before an array is illegal and/or that the >compiler simply ignores it. This is the K&R-1 (`Classic C') interpretation. In K&R-2/ANSI (`New C'), & before an array name produces a value with a different type. Given basetype arr[SIZE]; /* declares arr as `array SIZE of basetype' */ the type of `arr' is `array SIZE of basetype'. In a value context, such as the right hand side (but not the left side) of an assignment operator, an object of type `array N of T' degenerates to a value of type `pointer to T' whose value is the address of the 0'th element of the object. This is the same in both Classic C and New C. As the argument of the address-of operator `&', however, there is a difference. In Classic C, if the argument is an object of type `array N of T', the `&' is ignored (with a warning), while in New C, the result is instead a pointer to that object: a value with type `pointer to array N of T' whose value is the address of the object. Thus: arr produces a value of type `pointer to basetype', value = &arr[0], but &arr produces either a warning (Classic C), or a value of type `pointer to array SIZE of basetype' (New C). >To my understanding, the following *is* a type mismatch: >----------------------------------------------------------------------- >main() >{ > char a[10], (*p)[10]; > > p = a; >warning: illegal pointer combination, op = >} Yes, it is. To make it correct (but require New C): > p = &a; Unfortunately, when handed to an Old C compiler, you get: >warning: & before array or function: ignored >warning: illegal pointer combination, op = >And to all of you who want to now, why I might want to do such strange >things, look at the following: >----------------------------------------------------------------------- >main() >{ > char m[20][10], (*p)[10]; > > p = m[0]; > /* ^ to "&" or not to "&", that is the question */ In both Classic and New C, this can be expressed as p = m + 0; because `m' has type `array 20 of array 10 of char', and hence `m' in a value context (such as an operand of `+') produces a value of type `pointer to array 10 of char' whose value is the address of m[0]. In New C, of course, it can also be written p = &m[0]; since & accepts an object of type `array 10 of char' and produces a value of type `pointer to array 10 of char' whose value is the address of that object (m[0]). It is just those darned Classic C compilers that refuse to recognise this. > /* do something with (*p)[x] -- a single char > and have the possibility to increment p to > point to the next group of 10 char-s */ >} >----------------------------------------------------------------------- >or another one: >----------------------------------------------------------------------- >char (*foo())[10] >{ > static char m[20][10] = { > /* some initialization */ > }; > int i; > /* do some calculations giving a value to i */ > return m[i]; > /* ^ to "&" or not to "&", that is the question */ >} Again, `return m + i' is the only solution that works everywhere. Incidentally, if you have PCC source, you can add `&arr' to your Classic C compiler (the result is definitely an improvement) merely by *removing* several lines of code. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris