Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: char** to const char** conversion [duplicate]

Tags:

c++

types

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]
like image 801
scttrbrn Avatar asked Aug 16 '13 12:08

scttrbrn


People also ask

How Convert const char* to char*?

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.

Can a char * be passed as const * argument?

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 ...

Can const char * be reassigned?

Variables defined with const cannot be Redeclared. Variables defined with const cannot be Reassigned.

What is the difference between char and const char?

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.


1 Answers

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:

  1. invalid conversion from ‘char**’ to ‘const char**’
  2. Why am I getting an error converting a ‘float**’ to ‘const float**’?

EDIT: I got the 1st example wrong by a bit. Thank for pointing it out!

like image 154
luk32 Avatar answered Oct 05 '22 10:10

luk32