The first one (char** argv
) is defined by the C11 standard:
It shall be defined with a return type of int and with no parameters:
int main(void) { /* ... */ }
or with two parameters (referred to here as argc
and argv
, though any names may be used, as they are local to the function in which they are declared):
int main(int argc, char *argv[]) { /* ... */ }`
or equivalent¹⁰) or in some other implementation-defined manner.
¹⁰Thus, int
can be replaced by a typedef
name defined as int
, or the type of argv
can be written as char ** argv
, and so on.
You could argue that const char
is "equivalent" to char
in the way the C11 standard is defining it. However, the standard also says this about the parameters:
The parameters argc
and argv
and the strings pointed to by the argv
array shall be modifiable by the program, and retain their last-stored values between program startup and program termination.
So it would seem const
is not C standard.
This answer details if it's OK to modify main
parameters. The array char **argv
is allocated at runtime, and modifying it doesn't affect any program execution.
As to why const
isn't used as a declaration, it mainly boils down to historical practices. This question's answers detail why const char **argv
might be used instead of its non-const
.