0

Take this example:

int main()
{
   const char* what = "Is This";
   what = "Interesting";
   cout << *what;
   what[3] = 'a'; // Sytax Error: expression must be a modifiable lvalue
   cout << *what;

   return 0;
}

So I declare what as const char*, and I was able to reassign it another value (actual data in the memory - not the memory address itself).

But then, it tells me that I can't change the character that is on the 4th position!

Why is that?

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
Sandra K
  • 1,209
  • 1
  • 10
  • 21
  • 6
    In your example, `what` is modifiable. What it points to is not modifiable. – Eljay Mar 04 '19 at 20:20
  • See this question for how to read pointer declarations: https://stackoverflow.com/questions/1143262/what-is-the-difference-between-const-int-const-int-const-and-int-const – alter_igel Mar 04 '19 at 20:22
  • If you want a const pointer to a const thing you are looking for `const char* const what` – Jesper Juhl Mar 04 '19 at 20:25

2 Answers2

6

In this code, what is a non-const pointer to const char.

You can change what, but you cannot change *what.

If you want to declare a const pointer to const char, you need to write const twice:

const char *const what = "Is This";
// what is const
what = "Interesting"; // Error
// *what is also const
what[4] = 'x';        // Error

If you want a const pointer to non-const char, write it in a different place:

char isthis[] = "Is This";
char interesting[] = "Interesting";
char *const what = isthis;
// what is const
what = interesting; // Error
// *what is not const
what[4] = 'x';      // Ok
Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
3

const applies to the characters pointed not the pointer itself! So you can point to any C-string you want, but can't change the character of those strings.

For the sake of simplicity of the example, I will use another type to illustrate the point (C-strings literals can't be modified):

You actually have something like this

const int i = 666;
const int j = 999;
const int *pi = &i;
pi = &j;
// *pi=444; is invalid, can't change the int pointed by pi

You can built a pointer that cannot be changed but the int pointed:

int i = 666;
int j = 999;
int *const pi = &i;
*pi = 999;
// pi = &j; is invalid, pi will always point to i

And you can then mix both, never change the pointer nor the int pointed:

const int i = 666;
const int j = 999;
const int *const pi = &i;
// pi = &j; is invalid
// *pi = 444; is invalid
Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69