On Fri, Nov 24, 2000 at 07:50:34PM -0500, Greg Hudson wrote:
> >> It wasn't "const char *const *argv" before because a "char **"
> >> argument is not compatible with such a parameter, and C programs
> >> canonically take "char **argv", not "const char *const *argv". I'm
> >> not sure if it's even valid C to silently change from char * to const
> >> char * without an explicit cast, which is what you'd be doing if you
> >> wrote a main() which accepted a list of const char pointers intead of
> >> a list of char pointers.
>
> > Don't be silly, you can always pass a non-const value for a const
> > arg. Same with silent promotions of int to long, etc.
>
> The compiler can only promote the top-level parameter, not the
> contents of an array. Observe:
>
> equal-rites% cat test.c
> void foo(const char *const *a) { ; }
> void bar() { char **b = 0; foo(b); }
> equal-rites% gcc -c -Wall test.c
> test.c: In function `bar':
> test.c:2: warning: passing arg 1 of `foo' from incompatible pointer type
Yah, what GregH said :-)
I knew this, but we can always add "const" into our pointer types. It
clarifies what we're going to be doing with the values. And what Brane said
about the declaration needing to be "char *argv[]" is slightly bogus. While
that may be the "formal" declaration, you are NOT allowed to monkey with
that stuff.
I just tried this:
int main(int argc, char *argv[])
{
argv[1][0] = 'a';
return 0;
}
That dumps core *very* quickly :-)
In other words, the "true" declaration is "const char **argv". (I was able
to say "argv[0] = whatever" without a crash).
So... by stating the parameter is "const char * const *argv", we are saying
what we intend to do (or not do) with the arguments. And I think we really
ought to treat it as if those const qualifiers were on there.
Cheers,
-g
--
Greg Stein, http://www.lyra.org/
Received on Sat Oct 21 14:36:15 2006