Pointers vs. arrays: another dumb question...

Wayne Throop throopw at dg_rtp.UUCP
Wed Jun 25 05:20:38 AEST 1986


> allbery at ncoast.UUCP (Brandon Allbery)
> Okay, I've another dumb question for everyone:

A-Hah!  Not a dumb question at all!  It is a question that cuts right to
the center of the confusion about pointers in C.

At least... the *second* part of your question is most insightful.  I'm
not at all sure what the first part of your question *is*.  Let's
examine the first part before we get to the insight later:

There are two specific casts that are asked about, (struct foo (*)[])
and (struct foo *).  As I understand it, the question is, where should
each be used, and why.  No specific examples of the use of either cast
are given, but I conjecture from previous postings that the first cast
is used like so:

    int (*a[N])[];
    a[M] = (int (*)[]) malloc( (unsigned) O*sizeof(int) );

This is, of course, correct.  The second cast's use is much more
obscure... the only thing said about it is:

> But, if it's in initialized data, you can't do it that way:
> you can't take a ``pointer to an array''.
> So the cast is: (struct foo *)

Lacking an example of where this cast must be used, some questions
immediately spring to mind.  What "it" is in initialized data?  The
array or one of the the arrays pointed to?  What "it" is it that
"can't be done that way".  The cast?  The assignment (or maybe an
initialization)?  The malloc?  Finally, what "way" is being talked about
here?  The format of the assignment/initialization?  The method of
allocating storage?  Zen budhism?

If the declaration is of an array of pointers to array of int, then
there would be no pointer of type (int *) anywhere.  (NOTE: no *pointer*
of that type... there *would* be *addresses* of that type.  (Using
"pointer" to mean "an address lvalue".))  So, as I say, I have no idea
what this part of your question is talking about.  On the off chance
that the first "it" is "one of the arrays pointed to", the and second
"it" is "the malloc", I'd do *that* like so:

    int a1[O], (*a[N])[] = { ... (int (*)[])a1, ... };

Note however, this doesn't involve a cast to type (int *), so perhaps
that wasn't what was meant?


Anyhow, the insightful stuff follows:

> BUT:  the arrangement in memory is identical!

Yes.  The types (int *) and (int (*)[]) are refering to identical memory
layouts.  Note that they are *NOT* *NOT* *NOT* the same type just
because they refer to identical memory layout.  The *OPERATIONS* that
may be performed on objects of these types are different.

> So:  why isn't the correct type of an array name (struct foo (*)[])?

Let's ammend that slightly...
"Why isn't the correct type of an int array name (int [])?"

*GOOD* question.  *VERY* good question.  The answer is "just because".
Or, if you want to be insulting, because DMR slipped a cog.  This is
*THE* *MOST* *CONFUSING* thing about C, by far.  An array name, when
evaluated, does *NOT* *NOT* *NOT* yield an array type.  This is the
single greatest lunacy of the C language.  It might be argued that this
is the *ONLY* great lunacy in C, although the declaration-mirrors-use
rule probably ought to be considered a great lunacy as well.  (In case
you can't tell, these nasty remarks about array name evaluation in C are
my opinions only, and only about 60% serious.  Others differ with me.
However, it is objective fact that this one point causes more confusion
and error than any other construct in C.  By far.)

> That
> would make much more clear the meaning of the pointer, and would avoid many of
> the pointer-vs.-array confusions.

Yes, yes, yes!!!  However, the fact that array names evaluate to the
address of the first element in the array means that the types "pointer
to foo" and "pointer to array of foo" *must* indicate the same storage
layout in C, and this glitch is so deeply ingrained in C that to "fix"
it would simply yield a new language, not a better C language.  Note
that this glitch, coupled with the definition of subscripting in terms
of pointer arithmetic, makes the type "pointer to foo" an unresistably
convenient near-synonym for "pointer to unknown sized array of foo", and
thus nearly everybody uses the simpler form.

--
        Just because you wind up naked doesn't make you an emperor.
                                                --- Padlipsky
-- 
Wayne Throop      <the-known-world>!mcnc!rti-sel!dg_rtp!throopw



More information about the Comp.unix mailing list