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/