Jelo
Jelo

Reputation:

How to put values to const char **?

If I declare a variable const char ** stringTable, how should I be able to put values to it if it is a const? (It has to be const because a function I am supposed to use takes const char ** as a parameter.)

Edit: No you cannot convert from char ** to const char ** implicitly. Compiler complains: cannot convert parameter 3 from 'char **' to 'const char **'

Upvotes: 3

Views: 7487

Answers (8)

R Samuel Klatchko
R Samuel Klatchko

Reputation: 76601

const char ** indicates that the underlying character is constant. So, while you can't do something like this:

const char **foo = ...;
**foo = 'a';   // not legal

but there is nothing preventing you from manipulating the pointer itself:

// all the following is legal
const char **foo = 0;

foo = (const char **)calloc(10, sizeof(const char *));

foo[0] = strdup("foo");
foo[1] = strdup("baz");

That said, if you did want to modify the actual character data, you could use a non-const pointer and cast it:

char **foo = ...;
func((const char **)foo);

Upvotes: 0

Potatoswatter
Potatoswatter

Reputation: 137930

Wow, I'm surprised nobody got this! Maybe I can get a necromancer badge. Implicit const casting only scans one level deep. So a char* can become a const char* but it won't dig deep enough inside the a char** type to find what needs to be changed to make it a const char**.

#include <iostream>
using namespace std;

void print3( const char **three ) {
        for ( int x = 0; x < 3; ++ x ) {
                cerr << three[x];
        }
}

int main() {
         // "three" holds pointers to chars that can't be changed
        const char **three = (const char**) malloc( sizeof( char** ) * 3 );
        char a[5], b[5], c[5]; // strings on the stack can be changed
        strcpy( a, "abc" ); // copy const string into non-const string
        strcpy( b, "def" );
        strcpy( c, "efg" );
        three[0] = a; // ok: we won't change a through three
        three[1] = b; // and the (char*) to (const char*) conversion
        three[2] = c; // is just one level deep
        print3( three ); // print3 gets the type it wants
        cerr << endl;
        return 0;
}

Upvotes: 5

Pierre
Pierre

Reputation: 35306

you can un-const char* by using a cast operator: (char*)

void do_something(const char* s)
{
char* p=(char*)s;
p[0]='A';
}

use the same idea with the arrays char**

Upvotes: 0

Dave Costa
Dave Costa

Reputation: 48121

With my compiler (gcc version 3.4.4 in cygwin), I found that I could pass char * to const char *, but not char ** to const char **, unlike what most of the answers are saying.

Here is one way you can build something up that works; maybe it will help you.

void printstring( const char **s ) {
  printf( "%s\n", *s );
}

int main( int argc, char** argv ) {

  char *x = "foo";  // here you have a regular mutable string

  const char *x2 = x;  // you can convert that to a constant string

  const char **y = &x2;  // you can assign the address of the const char *

  printstring(y);


}

Upvotes: 1

Christoph
Christoph

Reputation: 169763

char ** can be converted to const char **, so if you want to call a function which takes a const char ** as a parameter, just supply your char ** and it'll be implicitly converted.

If you want to write a function which takes a const char ** as parameter and then modifies the char data it references, you're breaking the contract with your compiler, even if you might get it to work via casts!

Upvotes: 1

Alex B
Alex B

Reputation: 84952

Apart from other mentions that you can pass char** into function that takes const char **,

const char** is a non-const pointer to const char*, you can declare it and freely put values of type const char* in it.

On the other hand, you would not be able to do it, if you declared it as const char * const * or const char * const * const.

yourfunc(const char **p);
...
const char *array_str[10];
array_str[0] = "foo"; /* OK, literal is a const char[] */
yourfunc(array_str);

Here is what cdecl says:

cdecl> explain const char **table
declare table as pointer to pointer to const char
cdecl> explain const char * const *table
declare table as pointer to const pointer to const char
cdecl> explain const char * const * const table
declare table as const pointer to const pointer to const char

Upvotes: 4

Rowland Shaw
Rowland Shaw

Reputation: 38128

You can pass a char ** to a function declared as taking a const char ** -- Might be worth taking a look at the documentation for const on MSDN

Upvotes: 3

flolo
flolo

Reputation: 15526

That const declaration is a quarantee of the function, you dont have to fullfill it. That means the function will keep your array untouched (it will just read). So you can pass a nonconst variable to a function expecting const.

Upvotes: 3

Related Questions