Xref: utzoo comp.bugs.4bsd:1656 comp.std.c:4147 Path: utzoo!utgpu!news-server.csri.toronto.edu!bonnie.concordia.ca!uunet!cs.utexas.edu!execu!sequoia!rpp386!jfh From: jfh@rpp386.cactus.org (John F Haugh II) Newsgroups: comp.bugs.4bsd,comp.std.c Subject: Re: Bug in users command Message-ID: <18969@rpp386.cactus.org> Date: 21 Jan 91 03:52:10 GMT References: <18958@rpp386.cactus.org> <18928:Jan1916:26:3291@kramden.acf.nyu.edu> <18965@rpp386.cactus.org> <24748:Jan2016:53:4291@kramden.acf.nyu.edu> Reply-To: jfh@rpp386.cactus.org (John F Haugh II) Followup-To: comp.std.c Organization: Lone Star Cafe and BBS Service Lines: 62 X-Clever-Slogan: Recycle or Die. [ I'm redirecting this to the ANSI-C group because it seems that Dan has some misunderstanding about what the current standards say about passing arrays and their addresses. ] In article <24748:Jan2016:53:4291@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >> How does a pointer to an unknown number of characters differ from a >> pointer to a known number of characters when passed as an argument? > >It doesn't. It does, however, differ from a pointer to an *array* of >characters. How? When an array of any size, known or unknown, is passed as an argument to a function, the value which is passed is the address of the first element in the array. The address of an array, that is, the address of each member of "char names[MAXUSERS][UT_NAMESIZE]" where each member is an "array[UT_NAMESIZE] of type char", is the address of the first member of that array. >scmp() does not get passed a char [UT_NAMESIZE]. It gets passed a >pointer to a char [UT_NAMESIZE]. You claim there is an equivalence >between pointer to array of char and pointer to char? You claim it's >spelled out in K&R? I don't believe you. It gets passed the address of the first character in the "array[UT_NAMESIZE] of type char". K&R is explicit on this point. A "pointer to a char [UT_NAMESIZE]" is a pointer to a char with the value of the 0th element in the array. This is why "&x[0]" is identical to an unadorned "x" for all types of "x" and all sizes of the array of "x"'s. >Of course, most implementations use the same type for all pointers >internally. But what would happen on a machine where pointers to words >are stored differently (say as the number of bytes divided by 4) while >pointers to characters are stored as byte indices? Then scmp() will >treat its arguments as byte indices, when in fact they could be a factor >of 4 off. It really doesn't matter in this case. The "names" array is merely an "array [MAXUSERS][UT_NAMESIZE] of type char". Pointer arithmetic in this case is very well defined. The value of the pointer should be the address of the 0th element of the array, which is an "array [UT_NAMESIZE] of char". The value of that 0th element is again the address of the 0th element of the array, or a (char *) which points to the 0th character. The address of the 1st, 2nd, or nth element of the "names" array can then be computed by adding "n * UT_NAMESIZE" to the address of the 0th element. The only mistake which I see is that qsort() is called with a (char *) parameter, not (void *), but I believe that there is an explicit requirement that all (char *) pointers be identical to all (void *) pointers. Of course, a function which has (long *) as the parameter type =would= be called incorrectly by qsort() if it declared its parameters as (long *) and not (void *), but then by the rule above, (void *) and (char *) are indistinguishable. There are machines with bizarre pointer types, and I'm certain such a piece of code would be incorrect, but this particular code is just fine. -- John F. Haugh II UUCP: ...!cs.utexas.edu!rpp386!jfh Ma Bell: (512) 832-8832 Domain: jfh@rpp386.cactus.org "While you are here, your wives and girlfriends are dating handsome American movie and TV stars. Stars like Tom Selleck, Bruce Willis, and Bart Simpson."