35

Why does the following code in C work?

const char* str = NULL;
str = "test";
str = "test2";

Since str is a pointer to a constant character, why are we allowed to assign it different string literals? Further, how can we protect str from being modified? It seems like this could be a problem if, for example, we later assigned str to a longer string which ended up writing over another portion of memory.

I should add that in my test, I printed out the memory address of str before and after each of my assignments and it never changed. So, although str is a pointer to a const char, the memory is actually being modified. I wondered if perhaps this is a legacy issue with C?

MaxVT
  • 12,989
  • 6
  • 36
  • 50
Chris
  • 4,355
  • 5
  • 20
  • 12

5 Answers5

45

You are changing the pointer, which is not const (the thing it's pointing to is const).

If you want the pointer itself to be const, the declaration would look like:

char * const str = "something";

or

char const * const str = "something";  // a const pointer to const char
const char * const str = "something";  //    same thing

Const pointers to non-const data are usually a less useful construct than pointer-to-const.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • 1
    I did a test, however. I assigned str to a string and printed out the string and it's memory address. Then, I assigned str to another string and again, printed out the string and it's memory address. The string literal had changed but the address had not. – Chris Jan 13 '09 at 19:18
  • 1
    Did you print out the address of the pointer, or the address to which the pointer points? – mipadi Jan 13 '09 at 19:30
  • 1
    Thanks everyone. Yes, I was printing out the address of the pointer, not the data! What threw me off in this problem is how C deals with string literals. You can assign a string literal to a char* but you can't assign an integer to an int* in the same way, for example. – Chris Jan 13 '09 at 20:15
  • @Chris: that's because a string literal is actually a char[], which can be implicitly converted to a pointer to its first element – Christoph Jan 13 '09 at 21:24
16

Further, how can we protect str from being modified?

char * const str1; // str1 cannot be modified, but the character pointed to can
const char * str2; // str2 can be modified, but the character pointed to cannot
const char * const str3 // neither str3 nor the character pointed to can be modified.

The easiest way to read this is to start from the variable name and read to the left:

  • str1 is a constant pointer to a character
  • str2 is a pointer to a character constant
  • str3 is a constant pointer to a character constant

NOTE: the right-to-left reading does not work in the general case, but for simple declarations it's a simple way to do it. I found a java applet based on code from "The C Programming Language" that can decipher declarations with a full explanation of how to do it.

Eric Duminil
  • 52,989
  • 9
  • 71
  • 124
Matthew Crumley
  • 101,441
  • 24
  • 103
  • 129
  • Someone could cast away the const if they were really determined, but if the compiler places the chars in a read-only page then modifying them will cause a fault at runtime. – marklam Aug 05 '09 at 10:18
  • Technically the compiler and linker together. Switches depend on the tools you're using. – marklam Aug 05 '09 at 10:20
  • similar tool for English pointer description: https://cdecl.org/ – devwebcl Aug 21 '23 at 01:51
2

On a related note, definitely take a look at "const pointer versus pointer to const". It helps with what some people call const correctness. I keep it in my bookmarks so that I can refer to it every now and then.

  • That link has moved to here: https://voidnish.wordpress.com/2004/08/01/const-pointer-versus-pointer-to-const/ – Wilson F Feb 26 '16 at 01:42
1

What you're looking for may be the syntax...

const char* const str = NULL;
str = "test";
str = "test2";

Notice the "const" after the char* which yields a compiler error when trying to compile/build.

Rob Segal
  • 7,515
  • 12
  • 43
  • 72
1

Besides, declaring a variable as const means that variable is read-only; it does not mean the value is constant!

Kieran Tully
  • 433
  • 2
  • 6
  • 17