In C++, why is it not possible to pass a char**
as an argument to a function that accepts const char**
, when a conversion from char*
to const char*
is possible, as shown below
void f1(const char** a)
{
}
void f2(const char* b)
{
}
int main(int argc, char const *argv[])
{
char* c;
f1(&c); // doesn't work
f2(c); //works
return 0;
}
The compiler output is
test.cpp: In function 'int main(int, const char**)': test.cpp:15:10: error: invalid conversion from 'char**' to 'const char**' [-fpermissive] test.cpp:1:6: error: initializing argument 1 of 'void f1(const char**)' [-fpermissive]
You cannot explicitly convert constant char* into char * because it opens the possibility of altering the value of constants. To accomplish this, you will have to allocate some char memory and then copy the constant string into the memory. That is the only way you can pass a nonconstant copy to your program.
In general, you can pass a char * into something that expects a const char * without an explicit cast because that's a safe thing to do (give something modifiable to something that doesn't intend to modify it), but you can't pass a const char * into something expecting a char * (without an explicit cast) because that's ...
Variables defined with const cannot be Redeclared. Variables defined with const cannot be Reassigned.
Simple: "char *name" name is a pointer to char, i.e. both can be change here. "const char *name" name is a pointer to const char i.e. pointer can change but not char.
You need to protect contents on both levels of dereference of the pointer. With const char**
you could actually modify contents on the 1st dereference.
char *tmp = "foo"; //Deprecated but it's ok for the example
void f1(const char** a)
{
a[0] = tmp; //this is legal
a[0][1] = 'x'; //this is not
}
And this is most probably not intended. It should look like this:
char *tmp = "foo"; //Deprecated but it's ok for the example
void f1(char const* const* a)
{
a[0] = tmp; // this is not legal any more
a[0][1] = 'x'; // this still upsets compiler
}
The compiler does not allow implicit conversion to such "partially" protected pointer types. Allowing such conversion could have nasty consequences as discussed in c++faq
pointed out in comment by @zmb. This answer also cites how could you violate constness of an object if this was allowed, using char
examples.
One can however implicitly convert to a "fully" protected pointer as shown in the 2nd code example so below code compiles.
void f1(char const* const* a){}
void f2(const char* b){}
int main(int argc, char const *argv[])
{
char* c;
f1(&c); // works now too!
f2(c); // works
return 0;
}
Actually there is a bunch of questions and answers on this matter lying around. E.g:
EDIT: I got the 1st example wrong by a bit. Thank for pointing it out!
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