[comp.lang.c] Passing arrays of strings

torek@elf.ee.lbl.gov (Chris Torek) (04/06/91)

In article <11030@exodus.Eng.Sun.COM> bm@bike2work.Eng.Sun.COM
(Bill(Francis) Michel) writes:
>/* Help! I'm trying to intialize an array and pass it to a function,
>   massage it.

This question more properly belongs in comp.lang.c, where it is partially
answered by the Frequently Asked Questions list.

>   What's wrong with this picture?

>blop (instring, thearray)
>char	*instring;
>char	(*thearray)[];
>{

The first thing that should leap out at you here is

	char (*thearray)[];

This declares an object (a formal parameter) called `thearray' that has
the type `pointer to array of unknown size of char'.

You should avoid pointers to `array of unknown size': a `pointer to
array ?missing-size? of T' confers no power not already provided by a
`pointer to T'.

>	int	i;
>		
>	for (i=0; i<10; i++)
>	  {
>	  printf ("%s\n",thearray++);
>	  }
>}

Here your compiler has a bug: `thearray++' means `step forward one
whole object'.  A `whole object' in this case is one `arary of unknown
size of char', and the way one steps forward by one such object is by
adding 1 unknown value.  Clearly the result of adding one unknown value
is unknown, but your compiler blithely added 0 instead.

Gcc properly says:

	invalid use of array with unspecified bounds

for `thearray++'.

>main (argc, argv)
>int	argc;
>char	*argv[];
>{
>	char	myarray[10][ARRAY_LEN] ={{ "blop0" },

Here `myarray' is an `array 10 of array ARRAY_LEN of char', so each
element of `myarray' is an `array ARRAY_LEN of char'.  If `thearray'
above is to point to zero or more such elements, it must be declared as
a `pointer to array ARRAY_LEN of char'.

>	blop(argv[1], myarray);

Now we must invoke The Rule:

	In any value context, an object of type `array N of T' is converted
	to a value of type `pointer to T' by finding the 0'th element of
	that array.

Here the second argument to blop() is an <object, array 10 of array
ARRAY_LEN of char, myarray>, and this matches The Rule, so we set N=10
and T=`array ARRAY_LEN of char'.  The Rule tells us to rewrite this
as a value of type `pointer to T', so we get a <value, pointer to 
array ARRAY_LEN of char, &myarray[0]>.

From this we can conclude that if blop() declares its second parameter
as a `pointer to array ARRAY_LEN of char', and if there are no other
errors, the program will function in a predictable manner.  If blop()
uses any other declaration%, the types will not match up and the
behaviour of the program will be unpredictable.
-----
% A formal parameter declaration that superficially reads `array K of
  array ARRAY_LEN of char' is in fact a declaration meaning `pointer to
  array ARRAY_LEN of char', as there is a corollary to The Rule that
  applies only to formal parameters.  I advocate the avoidance of
  declarations that superficially read one way, but actually mean
  something else, for what I hope are obvious reasons.
-- 
In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 415 486 5427)
Berkeley, CA		Domain:	torek@ee.lbl.gov