[net.unix] argcargv

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