[comp.lang.c] double indirection

richw@rosevax.Rosemount.COM (Rich Wagenknecht) (02/11/88)

Could someone give a small example of a use of double indirection or
just explain when and where it's used. I've been using C for about
6 months and have yet to use this feature. More specifically I've
seen this:

  char **argv.

Now I've used char *argv[] many times but can't see how the two relate.

Thanks in advance.

-- 
Rich W

richw@rosevax.Rosemount.COM
Disclaimer: My views may not represent my own much less my employer's.

chris@trantor.umd.edu (Chris Torek) (02/13/88)

In article <4292@rosevax.Rosemount.COM> richw@rosevax.Rosemount.COM
(Rich Wagenknecht) writes:
>Could someone give a small example of a use of double indirection or
>just explain when and where it's used.

This sounds circular, but is precisely true:  One uses double indirection
where one needs two levels of indirection.  Two examples:

	char *cmds[] = { "foo", "bar", "baz", 0 };

	int
	cmdindex(s)
		char *s;
	{
		char **cmdp;

		for (cmdp = &cmds[0]; *cmdp != NULL, cmdp++)
			if (strcmp(s, *cmdp) == 0)
				return (cmdp - &cmds[0]);
		return (-1);		/* not there */
	}

and

	char *
	word(s, nextp)
		char *s, **nextp;
	{
		char *first;

		/* skip leading spaces */
		while (isspace(*s))
			s++;
		if (!isalnum(*s))
			return (NULL);	/* no word here */
		first = s;
		/* skip word characters */
		while (isalnum(*s))
			s++;
		if (*s == 0)		/* no more characters */
			*nextp = NULL;
		else {
			*s = 0;
			nextp = s + 1;
		}
		return (first);
	}

>... More specifically I've seen this:
>
>  char **argv.
>
>Now I've used char *argv[] many times but can't see how the two relate.

This is a special case.

IMPORTANT:
	There are no `array of <T>' types in C.  None.  There ARE
	`array <N> of <T>' types, just not `array of <T>' types.
	`array of int' does not exist; `array 4 of int' does.  The
	constant <N> is *required*.

Now then, on to parameters:
	There are no array parameters in C.  While you can declare
	a parameter as `array <N> of <T>', or even (belying what I
	said above) as `array of <T>', the parameter's type is NOT
	`array <N> of <T>'.  It is quietly adjusted by the compiler
	to `pointer to <T>'.

Given

	main(argc, argv)
		int argc;
		char *argv[];
	{

the compiler *really* sees `Function main: function returning int.
First parameter: argc, int.  Second parameter: argv, pointer to
pointer to char.  Code: ...'

Note that

	f(a)
		int a[][];
	{

is not a legal declaration, and even PCC (4.3BSD) does not accept
it.  This is because `array <N> of <T>' is adjusted to `pointer to
<T>', changing `array of array of int' (no <N>s) to `pointer to
array of int' (still no <N>!).

	f(a)
		int a[][10];
	{

*is* legal: the declaration `array of array 10 of int' is adjusted
to `pointer to array 10 of int', and now there is an <N> in all
the `array of <T>'s.  Likewise:

	f(a) int a[][][]; {		/* illegal */
	f(a) int a[][][4]; {		/* illegal */
	f(a) int a[][3][4]; {		/* legal */
	f(a) int a[2][3][4]; {		/* legal */

Note that in the last case, the declaration is changed from
`array 2 of array 3 of array 4 of int' to `pointer to array 3
of array 4 of int'---the `array 2 of' is forgotten entirely.
You can put any arbitrary constant in the first dimension of
a parameter declaration, because that constant is ignored.

NONE OF THE ABOVE APPLIES TO `ordinary' VARIABLE DECLARATIONS---
ONLY PARAMETER ARRAY DECLARATIONS ARE `adjusted'.
-- 
In-Real-Life: Chris Torek, Univ of MD Computer Science, +1 301 454 7163
(hiding out on trantor.umd.edu until mimsy is reassembled in its new home)
Domain: chris@mimsy.umd.edu		Path: not easily reachable

chris@trantor.umd.edu (Chris Torek) (02/13/88)

In article <2292@umd5.umd.edu> I wrote
-		/* skip word characters */
-		while (isalnum(*s))
-			s++;
-		if (*s == 0)		/* no more characters */
-			*nextp = NULL;
-		else {
-			*s = 0;
-			nextp = s + 1;
-		}

That last assignment should be

	*nextp = s + 1;

Sorry about that.
-- 
In-Real-Life: Chris Torek, Univ of MD Computer Science, +1 301 454 7163
(hiding out on trantor.umd.edu until mimsy is reassembled in its new home)
Domain: chris@mimsy.umd.edu		Path: not easily reachable

wes@obie.UUCP (Barnacle Wes) (02/22/88)

In article <4292@rosevax.Rosemount.COM>, richw@rosevax.Rosemount.COM (Rich Wagenknecht) writes:
> Could someone give a small example of a use of double indirection or
> just explain when and where it's used.

Yah, look in the source for compress.c - it's part of the netnews
sources.  Compress uses a large array (~800K) to compress or
un-compress files into.  On stupid processors which don't support
large arrays (such as the 286 I have), you have to map this into 64K
arrays somehow.  The way it is done in compress is actually create an
array of pointers to arrays of 64K or less in size.  You then
calculate the location of whatever array entity you are trying to
access by first deciding which of the arrays it is located in, and
then deciding which element of that particular array you are trying to
access.

-- 
    /\              -  "Against Stupidity,  -    {backbones}!
   /\/\  .    /\    -  The Gods Themselves  -  utah-cs!utah-gr!
  /    \/ \/\/  \   -   Contend in Vain."   -  uplherc!sp7040!
 / U i n T e c h \  -       Schiller        -     obie!wes