1

Wikipedia says "const" is "...a special kind of variable whose value cannot typically be altered by the program during its execution..."

If that is the case, why does this:

const char *words[4] = { "aardvark", "abacus", 
                             "allude", "zygote" };

    *words = "first";
    words[1] = "second";

    int wordCount = 4;

    int i;
    for (i = 0; i < wordCount; i++) {
        NSLog (@"%s is %d characters long",
               words[i], strlen(words[i]));
    }

have an output of: "first" "second" "allude" "zygote" (obviously with the length etc.)

I thought the whole point of "const" was to prevent the variable of being modified??

startuprob
  • 1,917
  • 5
  • 30
  • 45

2 Answers2

19

The const only applies to the char, i.e. the content of the strings themselves, but not to the array. If you want the content of the array to be constant as well, you need to add const to every level:

char const* const words[4] = { "aardvark", "abacus", "allude", "zygote" };
//   ^      ^
//   |      This makes words[x] = "abc"; fails.
//   |
//   This makes words[x][y] = 'a'; fails
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
3

Decipher the statement:

const char *words[4] = { "aardvark", "abacus", "allude", "zygote" };

This says, "I want an array of 4 pointers to constant characters. These constant characters should be..."

In memory you end up with this:

0x04, // The pointer to the array of words
0x14, 0x1d, 0x24, 0x3b, // The 4 pointers within words
'a','a','r','d','v','a','r','k','\0','a','b','a','c','u','s','\0',
'a','l','l','u','d','e','\0','z','y','g','o','t','e','\0'

Each one of those characters are not allowed to change. You can't do this because you'd be changing the letter:

words[0][0] = 'b';

Nobody said anything about those pointers though.

words[0] = "new string";

This results in you getting this in memory:

0x04, // The pointer to the array of words
0x42, 0x1d, 0x24, 0x3b, // The 4 pointers within words, note the first one changed
'a','a','r','d','v','a','r','k','\0','a','b','a','c','u','s','\0',
'a','l','l','u','d','e','\0','z','y','g','o','t','e','\0',
'n','e','w',' ','s','t','r','i','n','g','\0'

Notice that within memory, none of the original strings changed. The only two changes that occurred were:

1 - The first pointer within words changed to point at a new address. 2 - The characters for "new string" were added to memory at that new address.

Now decipher this statement:

 char const* const words[4] = { "aardvark", "abacus", "allude", "zygote" };

This says, "I want an array of 4 constant pointers to constant characters. These constant characters should be..." Those pointers are never allowed to point at anything else. Those characters are never allowed to be anything else.

The careful reader might ask about whether the pointer to the array needs to be made constant. The answer is... I'm not really sure. I want to say that it's implied that it's constant but I'm not quite certain and my laptop battery is about to die.

Hope it helps anyone else who happens upon this!

ArtOfWarfare
  • 20,617
  • 19
  • 137
  • 193