I have this simple code that compiles without errors/warnings:
void f(int&, char**&){}
int main(int argc, char* argv[])
{
f(argc, argv);
return
Jefffrey's comment references the standard, here it is:
4.2 Array-to-pointer conversion [conv.array]
An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue of type “pointer to T”. The result is a pointer to the first element of the array.
And a prvalue is:
A prvalue ("pure" rvalue) is an expression that identifies a temporary object (or a subobject thereof) or is a value not associated with any object.
You cannot bind a non-const reference to a temporary.
int& i = int(); // error
char* argv[] = { "", "", nullptr };
// the result of the conversion is a prvalue
char**& test = argv; // error
Therefore the following code will happily compile:
#include
void f(int& argc, char** const& argv){
std::cout << argv[0] << std::endl; // a
}
int main()
{
int argc = 2;
char* argv[] = { "a", "b", nullptr };
f(argc, argv);
return 0;
}
One important thing I glazed over is pointed out in Kanze's comment.
In the first example provided in the OP, char* argv[]
and char** argv
are equivalent. Therefore, there is no conversion.
std::cout << std::is_array::value << std::endl; // false
std::cout << std::is_array::value << std::endl; // false
std::cout << std::is_array::value << std::endl; // true
std::cout << std::is_same::value << std::endl; // true
std::cout << std::is_same::value << std::endl; // false