Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!samsung!uakari.primate.wisc.edu!uflorida!haven!mimsy!chris From: chris@mimsy.umd.edu (Chris Torek) Newsgroups: comp.lang.c Subject: Re: multi-d arrays and types Message-ID: <23269@mimsy.umd.edu> Date: 26 Mar 90 19:58:47 GMT References: <1990Mar26.155319.23986@ccu.umanitoba.ca> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 95 In article <1990Mar26.155319.23986@ccu.umanitoba.ca> rpjday@ccu.umanitoba.ca writes: > int calendar[12][31]; > int (*monthptr)[31]; >Clearly, calendar is a 2-d array in the sense that ANYTHING >in C is a 2-d array, since all arrays in C are technically >1-dimensional. Based on my understanding of arrays in C, >what calendar is is a 1-d array, whose elements themselves >are arrays of length 31 of integers. Right so far? OK. Right. >The variable "monthptr" is now declared as a pointer to >an array of length 31 of int, which SHOULD match with >the type of element of the array calendar, no? An element of `calendar' has type (int [31]); `monthptr' has type `(int (*)[31])', so: no. >Based on this, I write a loop to scan the elements of calendar, >the outermost loop looking like > for (monthptr = calendar; monthptr <= calendar[11]; monthptr++) The rule is: In a value context, an object of type `array N of T' (for any constant N and any suitable type T) turns into a value of type `pointer to T', whose value is the address of the first (0'th) element of the array. The first part is OK: monthptr = calendar; => = ; Now apply the rule: N=12, T=`array 31 of int': => = ; >My assumption is that the first assignment should not be a >problem, as we have a pointer being assigned the name of an array >whose elements have EXACTLY the same type as the pointer. >This, in fact, works. "monthptr++" also works as address >arithmetic increments monthptr by the length of an int[31]. Yes. >The weirdness is in the comparison which, while it works, >complains that the types are incompatible ("warning: illegal >pointer combination"). Because they are: monthptr <= calendar[11] => (I have skipped a few steps here but the idea should be clear.) N=31, T=`int': => >Putting an "&" in front of "calendar[11]" makes it even worse as the >compiler complains that I now have "& before array or function", tosses >the "&", then generates the first warning. This simply means you have an old (`Classic C') compiler rather than an ANSI (`New C') compiler. >The question is, just what the heck type is "calendar[11]"???? It *is* type `array 31 of int'; it *becomes* `pointer to int' because it is used where a value is needed. >It seems to me that what I am seeing is some sort of schizophrenic >behaviour. This is the reason (or one of the reasons) that ANSI C allows the `&'. The solution to the whole problem is to replace monthptr <= &calendar[11] /* correct in ANSI C only */ with monthptr <= calendar + 11 /* correct in ANSI & old C */ which has the same effect but does not invoke the unnecessary restriction on `&' in old C compilers. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris