I have this simple code that compiles without errors/warnings:
void f(int&, char**&){}
int main(int argc, char* argv[])
{
f(argc, argv);
return
Because despite appearances, the second argument to main has
type char**. When used as the declaration of a function
argument, a top level array is rewritten to a pointer, so char
*[] is, in fact, char**. This only applies to function
parameters, however.
A char*[] (as in your second case) can convert to a char**,
but the results of the conversion (as with any conversion) is an
rvalue, and cannot be used to initialize a non-const reference.
Why do you want the reference? If it is to modify the pointer,
modifying the char** argument to main is undefined behavior
(formally, in C, at least—I've not checked if C++ is more
liberal here). And of course, there's no way you can possibly
modify the constant address of an array. And if you don't want
to modify it, why use a reference?