Xref: utzoo comp.bugs.4bsd:1657 comp.std.c:4153 Path: utzoo!utgpu!news-server.csri.toronto.edu!bonnie.concordia.ca!thunder.mcrcim.mcgill.edu!snorkelwacker.mit.edu!mintaka!yale!cmcl2!kramden.acf.nyu.edu!brnstnd From: brnstnd@kramden.acf.nyu.edu (Dan Bernstein) Newsgroups: comp.bugs.4bsd,comp.std.c Subject: Re: Bug in users command Message-ID: <6182:Jan2222:06:3991@kramden.acf.nyu.edu> Date: 22 Jan 91 22:06:39 GMT References: <18965@rpp386.cactus.org> <24748:Jan2016:53:4291@kramden.acf.nyu.edu> <18969@rpp386.cactus.org> Organization: IR Lines: 75 For comp.std.c readers: This argument started when I said that the BSD users.c appears to be incorrect. It passes a two-dimensional character array to qsort(), but the comparison function was expecting just a pointer to characters. John says that's correct. In article <18969@rpp386.cactus.org> jfh@rpp386.cactus.org (John F Haugh II) writes: > [ 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. ] Really? Then why can't you point out my mistake? Suppose you have the following: foo(s) char *s; { ... } char c[300][500]; foo(&(c[17])); Is this correct? I see it this way. c is an array of array of char. c[17] is an array of char. &(c[17]) is a pointer to an array of char. foo does not expect a pointer to an array of char; it expects a pointer to char. We all know that the value of an array is the value of a pointer to the first element of an array. But that doesn't apply here. Is there a conversion that says ``a pointer to c[17] is a pointer to c[17][0]''? I don't see any justification for that in K&R. I certainly wouldn't use such a coding style, and I hope Saber-C and other program checkers complain about it. Now John is right that this code will work on most real machines---pcc will even throw away the & in &(c[17]) and complain about it. But suppose you have a machine where pointers to characters are stored as byte addresses, while all larger pointers are aligned on word boundaries and then divided by 4 internally. Then &(c[17]) will be a factor of 4 different from &(c[17][0]), and the code will fail miserably. > 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, There is no array being passed. A *pointer* to the array is being passed. > 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. We're talking about C pointers, not their most common implementation. > >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. Where? > 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. No. Your second sentence is correct, but it is not logically connected to the previous sentence. ---Dan