I have this simple code that compiles without errors/warnings:
void f(int&, char**&){}
int main(int argc, char* argv[])
{
    f(argc, argv);
    return 0;
}
And next similar code that doesn't compile:
void f(int&, char**&){}
int main()
{
    int argc = 2;
    char* argv[] = { "", "", nullptr };
    f(argc, argv); 
    //@VS2013 error: cannot convert argument 2 from 'char *[3]' to 'char **&'
    //@GCC error: invalid initialization of non-const reference of type 'char**&' from an rvalue of type 'char**'
    return 0;
}
Why char*[] can be converted to char**& in the first sample and can't be converted in the second sample? Does it matter if the size is known at compile time?
EDIT: I think there are 2 conversions needed in the second case, and only one implicit conversion can be done by compiler.
This code compiles fine:
void f(int&, char**&){}
int main()
{
    int argc = 2;
    char* temp[] = { "", "", nullptr };
    char** argv = temp;
    f(argc, argv);
    return 0;
}
                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? 
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With