[net.unix] Pointers vs. arrays: another dumb question...

allbery@ncoast.UUCP (Brandon Allbery) (06/21/86)

Expires:

Okay, I've another dumb question for everyone:

In an application I wrote, I use pointers to arrays.  Now:

If the array is malloc'ed, the correct cast is:

		(struct foo (*)[])

and you assign the ``pointer to the array'' to a variable.  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 *)

BUT:  the arrangement in memory is identical!  It should be even on tagged
architectures, etc.; in fact, (struct foo *) is always wrong, and might
conceivably cause problems on a tagged architecture if you're really pointing
to an array.

So:  why isn't the correct type of an array name (struct foo (*)[])?  That
would make much more clear the meaning of the pointer, and would avoid many of
the pointer-vs.-array confusions.

--Brandon
-- 
ihnp4!sun!cwruecmp!ncoast!allbery ncoast!allbery@Case.CSNET ncoast!tdi2!brandon
(ncoast!tdi2!root for business) 6615 Center St. #A1-105, Mentor, OH 44060-4101
Phone: +01 216 974 9210      CIS 74106,1032      MCI MAIL BALLBERY (part-time)

tanner@ki4pv.UUCP (Tanner Andrews) (06/23/86)

) ncoast!allbery writes on the matter of casting a pointer to an
) array of pointers to a struct.

For the purposes of malloc casting, I would suggest neither of:
	(struct foo *)malloc( )
	(struct foo (*)[])malloc( )

Try instead the construct:
	(struct foo **)malloc( )

Consider that you are generating an array of pointers; what you are
getting back from malloc() is a pointer to this array.  Actually, it
points at the first pointer.

The same declaration would be appropriate for the variable, of
course:
struct foo
	**my_ptr;

-- 
<std dsclm, copies upon request>	   Tanner Andrews

throopw@dg_rtp.UUCP (Wayne Throop) (06/24/86)

> allbery@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