multi-d arrays and types
Chris Torek
chris at mimsy.umd.edu
Tue Mar 27 05:58:47 AEST 1990
In article <1990Mar26.155319.23986 at ccu.umanitoba.ca>
rpjday at 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;
=> <object, ptr to array 31 of int, monthptr> =
<object, array 12 of array 31 of int, calendar>;
Now apply the rule: N=12, T=`array 31 of int':
=> <object, ptr to array 31 of int, monthptr> =
<value, ptr to array 31 of int, &calendar[0]>;
>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]
=> <object, ptr to array 31 of int, monthptr> <compare>
<object, array 31 of int, calendar[11]>
(I have skipped a few steps here but the idea should be clear.) N=31,
T=`int':
=> <object, ptr to array 31 of int, monthptr> <compare>
<value, ptr to int, &calendar[11][0]>
>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 at cs.umd.edu Path: uunet!mimsy!chris
More information about the Comp.lang.c
mailing list