double indirection

Chris Torek chris at trantor.umd.edu
Sat Feb 13 18:06:42 AEST 1988


In article <4292 at rosevax.Rosemount.COM> richw at 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 at mimsy.umd.edu		Path: not easily reachable



More information about the Comp.lang.c mailing list