buck%nrl-css@sri-unix.UUCP (12/09/83)
From: Joe Buck <buck@nrl-css> As was pointed out, argc[argv] is the same as argv[argc], since the compiler translates it into *(argc+argv). The latter expression is clearer, obviously; it's just a pointer to the last argument on the command line, which seems like a useful construct.
gwyn%brl-vld@sri-unix.UUCP (12/09/83)
From: Doug Gwyn (VLD/VMB) <gwyn@brl-vld> Sorry, argv[argc] points AFTER the last command-line argument, not AT it.
vmicro1@ucbtopaz.CC.Berkeley.ARPA (12/14/83)
One thing I enjoy doing to test the whimsy of C compilers is: char *x; char y; y = x[1]; y = 1[x]; What sort of code (if any) do the two lines generate? Theoretically, they are identical; at least one compliler (VAX-11C under VMS) complains (it requires an lvalue in the second form); most let it slide. ----
gwyn%brl-vld@sri-unix.UUCP (12/17/83)
From: Doug Gwyn (VLD/VMB) <gwyn@brl-vld> If the VAX/VMS C compiler complains about char *x, y; y = 1[x]; then it is in violation of the C language rules, which explicitly state that a[b] is entirely equivalent to *(a+b) where the "+" is interpreted appropriately (and is commutative). I don't have any of the C reference manuals around at the moment but I know this is in there.
vmicro1%ucbtopaz.CC%berkeley@sri-unix.UUCP (12/18/83)
ve any of the C reference manuals around at the moment but I know this is in there. ...You are right, of course. VAX11C departs from the UNIX philosophy of keeping the C compiler a compiler only; that is, it includes stuff like cross-referencing and portability checking (all optional) as well as (gottenu!) making nice listings. I suspect that is barfs on 1[x] because of cross-referencing confusion, or some such. This is mostly moot, of course: do you know any particular reason why anyone would WANT to use 1[x]? Incidentally, VAX11C has by far the best error handling I have ever seen in a C compiler, including attempting to "do what the programmer thinks". For example, it will attempt to insert missing ; } or ) so as to continue compiling. Pretty good accuracy. It is also fast; as far as I can tell, it is a three-pass (rather than the usual four-pass) compiler, not generating human-readable machine language (unless specifically requested to). It adds a few strange things to establish mixed-language capabilities, maintaining consistancy with other VMS compilers (for example, equates in Macro programs can be accessed); however, it is all optional, and (so far) any Unix C program that does not use extremely Unix-specific calls (and I mean extremely; most of the Unix calls are there) seems to compile just fine. Oh yes, run just fine, also. josh
gam@proper.UUCP (Gordon Moffett) (12/18/83)
Why are we talking about this? Does anyone really say argc[argv]? If they do shouldn't we get them help soon? Gordon Moffett (just this guy, you know?)
Laws@SRI-AI.ARPA (12/18/83)
From: Ken Laws <Laws@SRI-AI.ARPA> Beginners may have trouble with the statement that a[b] is entirely equivalent to *(a+b). This is only true for character arrays. For other types of arrays the translation is *(a+b*sizeof(*a)). -- Ken Laws -------
edhall%rand-unix@sri-unix.UUCP (12/19/83)
In C the addition of an integer to a pointer implicitly does the multiplication you attempt to do explicitly (i.e., your example ends up doing the multiplication twice). This follows from the rules for C pointer arithmetic, in which adding to a pointer works in units of N bytes, where N is the size of the object pointed to. (Look it up in K & R...) The equivalence of a[i] and *(a+i) works for all pointers `a' and integer types `i'. Perhaps you were confused by the need for the multiplication in assembler-language programming. -Ed Hall edhall@rand-unix (ARPA) decvax!randvax!edhall (UUCP)
Lepreau@UTAH-20.ARPA (12/19/83)
From: Jay Lepreau <Lepreau@UTAH-20.ARPA> Nope, a[b] == *(a+b) for all arrays, not just char arrays, at least in "modern" (since v7 at least) C compilers, which know the size of *a already and use it in "scaling b". They don't just add plain "b" to it. Explicitly including sizeof would lose cause it would then be done twice. -------
gwyn%brl-vld@sri-unix.UUCP (12/19/83)
From: Doug Gwyn (VLD/VMB) <gwyn@brl-vld> RONG. a[b] is entirely equivalent to *(a+b), as stated. You have to remember what "+" means when adding a pointer and a constant.
jhh@ihldt.UUCP (12/20/83)
From: Ken Laws <Laws@SRI-AI.ARPA> Beginners may have trouble with the statement that a[b] is entirely equivalent to *(a+b). This is only true for character arrays. For other types of arrays the translation is *(a+b*sizeof(*a)). -- Ken Laws ------- a[b] IS equivalent to *(a+b) for all types of arrays. The addition is 'special' in that the result of a+b is a+b*sizeof(*a) for all a that are type pointer to something and b int. Beginners probably have trouble with the statement that a+b != (int)a + b for all types of a except char * and other non-pointers. John Haller
keesan@bbncca.ARPA (Morris Keesan) (12/20/83)
--------------------------------- >>>>Beginners may have trouble with the statement that a[b] is entirely >>>>equivalent to *(a+b). This is only true for character arrays. For >>>>other types of arrays the translation is *(a+b*sizeof(*a)). >>>> >>>> -- Ken Laws ------- Wrong. Even going by the assumption here that a is an array, then given the declaration "foo a[];" the expression a[b] is equivalent to *(a+b), and not *(a+b*sizeof(*a)), because the the scaling of b is done implicitly by the addition operator -- see the C Reference Manual, section 7.4 (p. 188 of K&R), which says in the case (pointer + int) "the latter is . . . [multiplied by] the length of the object to which the pointer points." Ken Laws is assuming integer addition, which is clearly not the case. What he means is that a[b] is equal to *(foo *)((int)a + b*sizeof(*a)), which is indeed equivalent to *(a+b). As several other people have pointed out, argc[argv] is indeed equivalent to argv[arc] and (argv+argc) and (argc+argv). The key to the confusion is brought out by the 5th paragraph of Section 7.1 of the reference manual (P. 186, par. 3 of K&R), which states that (primary expression)[expression] "is a primary expression. The INTUITIVE meaning is that of a subscript. USUALLY, the primary expression has type "pointer to ...", the subscript expression is int, and the type of the result is "...". The expression E1[E2] is identical (by definition) to *((E1)+(E2))." [caps mine]. The other useful section to read is section 14.3 (p. 210 of K&R), which repeats the definition of E1[E2], and points out that "despite its assymetric appearance, subscripting is a commutative operation." -- Morris M. Keesan {decvax,linus,wjh12}!bbncca!keesan keesan @ BBN-UNIX.ARPA
alan@allegra.UUCP (Alan S. Driscoll) (12/24/83)
From: Laws@SRI-AI.ARPA Newsgroups: net.unix Subject: argc[argv] From: Ken Laws <Laws@SRI-AI.ARPA> Beginners may have trouble with the statement that a[b] is entirely equivalent to *(a+b). This is only true for character arrays. For other types of arrays the translation is *(a+b*sizeof(*a)). -- Ken Laws No, that's incorrect -- "a[b]" is equivalent to "*(a+b)". If "a" is a pointer, and "b" an integer, then the multiplication you described will take place, but not for the reason you gave. The multiplication is a result of the way the "+" operator is defined in C. In "*(a+b)", the very same multiplication will take place. Alan S. Driscoll AT&T Bell Laboratories