I suspect I'm missing a broader concept here.
It looks to me like the broader concept you're missing is actually
pointers and arrays, not pointers to pointers.
You may find further enlightenment at
http://www.c-faq.com/aryptr/index.html
and at
http://groups.google.com/groups?q=group:comp.lang.c+author:"chris+torek"+"the+rule"
Okay, given the following
code:
#include <stdio.h>
int main(void) {
char *ptr[] = {"Garbage", "test", "work"};
ptr is an array of pointer to char with a slightly confusing name (since
it isn't actually a pointer).
Like any other array, it will be converted to a pointer to its first
element in most places you'll use it.
....and arg is a pointer to pointer to char, which can point at any element
of ptr[] (in particular, the first one that you get when you just say
`ptr' in a value context).
This does:
Convert ptr (array of pointer to char) into a pointer to its first
element (with type pointer to pointer to char).
Store that value in arg.
printf("The string is: %s\n", ptr[1]);
return 0;
}
Why am I not allowed to do something like:
arg = &ptr; ?
Giving it to the & operator like you're doing here is one of the
places where an array name *doesn't* get converted to a pointer[1].
The right-hand side of this assignment is a pointer to the array (with
type "pointer to array 3 of pointer to char"), and you're trying to
assign it to a pointer to pointer; since there's not a defined way to
convert from one of those types to the other (and not really a sensible
way either), the compiler complains.
I guess even more to the point, why is this legal?
arg = &(*ptr) ;
ptr gets converted to a pointer to its first element, and then you follow
that pointer, so the expression inside the parens identifies an object
of type pointer to char.
Then the & operator gives you a pointer to that object, with type
pointer to pointer to char. Since this is the same type of the object
you're storing it into, this works with no problems or complaints from
the compiler.
(This one is actually a special case of a more general rule: since & (get
pointer) and * (follow pointer) are inverse operations, saying "&(*p)"
will always give you the same value as just saying "p" for any pointer p,
and "*(&x)" will always give you the same object as just saying "x".)
Note that none of this actually needed us to know that ptr was an array
of pointers - everything would have worked the same way if it were, say,
an array of ints (as long as arg was a pointer the same type that ptr
was an array of). Pointers to pointers are just like pointers to any
other type: you can dereference a "foo *" to get a value of type "foo",
even if "foo" is a pointer type itself.
dave
[1] The other one you're likely to come across is when it's the operand
of the sizeof operator. I'm not going to complain that those are
the only two places it happens, but they're the only ones I can
recall ever having come across.