[net.lang.c] More on pointers/arrays: Function Arguments

brownell@harvard.UUCP (Dave Brownell) (04/10/84)

I saw this gem in a recent book on C programming by Thomas Plum,
"Learning to Program in C".  (It's much more tutorial than K&R;
I'm told it's very understandable, but my only exposure to it
is answering a few questions.)

    char *index (s, c)
	char s [], c;
    {
	while (*s != '\0' && *s != c)
	    ++s;				/* AARGH!! */
	return (*s == c ? s : NULL);
    }

This passes through Berkeley CC and LINT unscathed, and compiles.
Yet K&R Appendix A Section 14.3 Sentence 2 (sound biblical?) says
"...arrays are not lvalues" and Section 7.2 clearly states
autoincrement as "++ lvalue".  Hmmm ...


	Dave Brownell
	{genrad|allegra|ihnp4|ima|amd70}!wjh12!sequoia!brownell

gwyn@brl-vgr.ARPA (Doug Gwyn ) (04/11/84)

A formal parameter like
	type	parm[];
is fully equivalent to
	type	*parm;
since you cannot pass arrays as actual arguments (only pointers to them).
Compilers that are careful about lvalues treat both cases of `parm' as
lvalues.

keesan@bbncca.ARPA (Morris Keesan) (04/11/84)

------------------------------

Dave Brownell (sequoia!brownell) gives an example of code of the sort

        foo(s)
	char s[];
	{
	    . . .
	    ++s;    /*AARGH*/
	}

and objects to the ++s because "arrays are not lvalues" and ++ is explicitly
defined as "++ lvalue".  The given code is actually correct, although poor
style, because of the following, from the last paragraph of section 10.1 of the
C Reference Manual (p. 205 of K&R)

    Also, since a reference to an array in any context (in particular as an
    actual parameter) is taken to mean a pointer to the first element of the
    array, declarations of formal parameters declared "array of ..." are
    adjusted to read "pointer to ...".  

Somewhat more clearly put, perhaps, though not part of the language definition,
is the sentence on page 95 of K&R which says "As formal parameters in a
function definition, char s[]; and char *s; are exactly equivalent;"

    What this means is that in the context of the function foo(), above, s is
not an array, it is a pointer, and is thus an lvalue.  This one case of the
equivalence of s[] and *s is also the source of the recently discussed
confusion when people try to use them equivalently other than in parameter
declarations.
-- 
					Morris M. Keesan
					{decvax,linus,wjh12,ima}!bbncca!keesan
					keesan @ BBN-UNIX.ARPA

jbf@ccieng5.UUCP (04/12/84)

>    char *index (s, c)
>	char s [], c;
>    {
>	while (*s != '\0' && *s != c)
>	    ++s;				/* AARGH!! */
>	return (*s == c ? s : NULL);
>    }
>
>This passes through Berkeley CC and LINT unscathed, and compiles.
>Yet K&R Appendix A Section 14.3 Sentence 2 (sound biblical?) says
>"...arrays are not lvalues" and Section 7.2 clearly states
>autoincrement as "++ lvalue".  Hmmm ...

The argument s is actually a string pointer rather than an array.  In
K&R's reference manual Section 10.1 "External Function Definition", it
states in the penultimate sentence of the last paragraph that
"declarations of formal parameters declared 'array of' are adjusted to
read 'pointer to..' ".

Azhrarn
-- 
Reachable as
	....allegra![rayssd,rlgvax]!ccieng5!jbf

brownell@harvard.UUCP (Dave Brownell) (04/13/84)

----

More succinctly than I said it before,

    Whatever happened to "An array is an array is an array?"

Seeing an array incremented was a rude shock.  I know (now)
that it *SHOULD* be legal, but I've seen so many beginning
C programmers confused by pointers and arrays that the
example in the text I saw still offends me.

I'll continue to use '&array[0]' to get pointers to arrays ...


	Dave Brownell
	{genrad|allegra|ihnp4|ima|amd70}!wjh12!sequoia!brownell

ptw@vaxine.UUCP (P. T. Withington) (04/13/84)

...*s and s[] equivalent as function arguments...

From a stylistic point of view I was always lead to believe the former
was preferable when you intended to s++.
Anyone care to expand on this concept as it applies to argv?

**argv                  Preferred when you intend to argv++
*argv[]                 Preferred when you will argv[i]
argv[][]                Hm.