Perplexed by pointers

Jim Vlcek vlcek at mit-caf.MIT.EDU
Fri Nov 25 15:58:59 AEST 1988


A little note on Carl Paukstis' problems with a (char **) cast and
dereferencing of a (void *) pointer.  Just to refresh your memories, a
brief insert from Doug Gwyn's last posting on the matter:

*In article <2176 at iscuva.ISCS.COM> carlp at iscuva.ISCS.COM (Carl
*Paukstis) writes:
*->>86           code = strcmp (key, *(char **)((char *)table + (m * size)));
*->Line 86 is okay, but you really don't need to cast to a (char**) then
*->dereference to get the (char*) key.  That's extra work that amounts to
*->a no-op.
*-  Huh?  The type of the expression ((char *)table + (m * size)) is
*-  "pointer to char", no?  And the usage on line 86 requires "pointer to
*-  pointer to char".  If I dereference the subexpression above, e.g.
*-  *((char *)table + (m * size)), the result type is "char", not "pointer
*-  to char" as required by strcmp().  Or am I just being dense?
*
*That's not what I said!
*
*You already had a (char *).  You then cast it to (char **), and then
*dereferenced that using the * operator.  There was no need for these
*extra steps when the original (char *) was just what you needed.
*(strcmp takes (char *) arguments.)

Carl is in fact completely right on this one, and the way in which he
did the operation is exactly the right way.  Consider:

``table'' is a pointer to an array of structures, each of size
``size'', and whose first element is a pointer to char (char *).  He
needs to pass one of these pointers to strcmp().  Since it is the
pointers which are contained in ``table,'' not the actual strings to
be compared, obviously a dereference needs to be performed to be able
to pass the correct value to strcmp().

Since the routine to which ``table'' is passed has no idea what kind
of structures comprise this array, it is given the size of each
structure as ``size.''  Hence, casting ``table'' to (char *) and
adding m*size to it are perfectly correct; this then yields a pointer
to the m-th array entry (structure-wise) in ``table.''  Since the address
of the first element of any structure is also the address of the
structure itself (suitably cast), this value is then also the address
of the first element in the structure -- this so happens to be a
pointer to char.  Hence, the cast to (char **) is appropriate.  One
then dereferences this to get the actual pointer value, passes it to
strcmp(), and voila!

People here paid too much attention to the pointer types, and not
enough attention to the values!  The original cast to (char *) is only
done to be able to correctly perform the necessary pointer arithmetic,
for in fact ``table'' is in no sense really a pointer to char.  I'm
suprised that the notion of *(char **) amounting to a no-op managed to
breeze by Doug Gwyn!
-- 
Jim Vlcek
vlcek at caf.mit.edu
!{harvard,rutgers}!mit-eddie!mit-caf!vlcek



More information about the Comp.lang.c mailing list