It's legal, (well, modulo envp, which is obsolete, and not a part of any
standard; use extern char **environ for POSIX.) but only because the
promoted types of int and char ** are int and char **.
The construct
void foo(char);
void foo(c)
char c;
{}
*IS NOT LEGAL NOW*. It invokes undefined behavior, because foo is declared to
accept a char by the declaration, but an int by the definition, because the
old-style rule is that the standard promotions are applied to function
arguments.
My ideal solution is to declare that
void foo(c)
char c;
{}
acts *EXACTLY* like
void foo(char c);
in C9X programs. Since the old-style declarations are obsolescent, any
code broken by this had it coming. (Regardless, C9X is almost guaranteed
to have either the "prototype-equivalent" old-style definitions, or none
at all.)
People who need to use old code can do what they do now; use gcc -traditional.
-s