Path: utzoo!utgpu!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!ukma!rutgers!mit-eddie!mit-amt!mit-caf!vlcek From: vlcek@mit-caf.MIT.EDU (Jim Vlcek) Newsgroups: comp.lang.c Subject: Perplexed by pointers Message-ID: <1537@mit-caf.MIT.EDU> Date: 25 Nov 88 05:58:59 GMT References: <2172@iscuva.ISCS.COM> <8954@smoke.BRL.MIL> <2176@iscuva.ISCS.COM> <8976@smoke.BRL.MIL> Reply-To: vlcek@mit-caf.UUCP (Jim Vlcek) Organization: Microsystems Technology Laboratories, MIT Lines: 54 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@iscuva.ISCS.COM> carlp@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@caf.mit.edu !{harvard,rutgers}!mit-eddie!mit-caf!vlcek