Bug in users command

John F Haugh II jfh at rpp386.cactus.org
Mon Jan 21 14:52:10 AEST 1991


[ 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 at kramden.acf.nyu.edu> brnstnd at 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 at 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."



More information about the Comp.bugs.4bsd.ucb-fixes mailing list