Question

Possible Duplicate:
Modifying C string constants?
Pointer to const char vs char array vs std::string

I know I'm probably beating the dead horse with this question, but I'm a little confused and I haven't managed to find an exact answer on SO or google (that I'm confident is right - there's just too much information on C-strings to sift through). Also, I've tagged it C++ because that's what I'm interested in, even though we're talking about C-style strings specifically.

In this situation:

char const a*  = "hello";
char const b[] = "goodbye";

I would have thought that "hello" and "goodbye" were both immutable strings because they come from string-literals that should decay to a char const*.

I've seen that in this particular case though, changing "hello" would be undefined while changing "goodbye" would be fine, assuming you stripped the constness from the b-array.

I assume that the string is mutable in the case of b due to the fact that its stored in a user-defined array.

Are hello and goodbye different in this case? Is goodbye not a string-literal for some reason given this example. Also, if goodbye isn't a string-literal, can I assume it isn't held in global memory, and the only reference to it after compile time is that which is left in the user-array cells?

Was it helpful?

Solution

The first one creates a pointer that points to the string literal "hello", which is probably stored in non-writable memory in the executable image of the program. Even if it isn't, you are not allowed to modify the contents of that array.

The second one creates an automatic array1 (on the stack (usually, but that is implementation-defined)) and initialises it with the string "goodbye". It is equivalent to

char const b[] = {'g', 'o', 'o', 'd', 'b', 'y', 'e', 0};

So while "goodbye" is immutable because it is a string literal which is char const[8] and stored in non-writable memory, the array b is an automatic1 array that is immutable because you marked it const, but you could remove the const from the variable declaration to make the array's contents mutable. You are only initialising the contents of the array with the contents of the array "goodbye".

You are not allowed to modify either of them because they are both const char[], but the second one could be changed to char[] to be mutable, while the first one could not.

See this answer for more info: https://stackoverflow.com/a/9106798/726361


1 As R. Martinho Fernandes pointed out in the comments, the syntax T x[] = ... could also create a static array (not automatic but static (in the executable image usually, but that's implementation defined)) if it is at namespace scope, and it's only an automatic array otherwise.

OTHER TIPS

A string literal has type char const[N]; of course a name of this type may decay to a char const*.

Now:

  1. A char array may be initialised by a string literal (8.5.2/1), and since you cannot otherwise copy or assign arrays, it follows that this initialisation implements a copy. You're free to do with the new, mutable array whatever you like.

    char str[6] = "hello";
    
  2. Conversely, when initialising a pointer, you're obtaining a pointer that's the result of the string literal's immutable array type decaying.

    char const* str = "hello";
    

    There is no new array here. Just copying a pointer to the existing, immutable data.

They are different. a points to a string literal that you cannot change. However, b is an array of characters that is initialized with the given string. Assuming the const were removed, then you can change the contents of b.

Yes they are different.

It is true that the string literals themselves ("hello" and "goodbye") are immutable. However, when you are accessing b, you are not accessing your original "goodbye". The code that you used declared a completely independent array b, which is only initialized with a string literal "goodbye". Your 'b' is totally independent from the original string literal "goodbye". Your b is a copy of that string literal. The only reason your 'b' is immutable is the const you explicitly included in its declaration. Remove that const and your b will become perfectly mutable, as any ordinary array is.

As for your 'a', it is a pointer that points directly to the original string literal "hello". It is, of course, immutable.

Both options are immutable, but not because they're created from a string literal. They're immutable because of the const keyword in the variable declarations.

You could also write char c[] = "string_c"; and you would create a mutable copy (named c) of the literal string_c.

In your example about removing the constness of b, that may appear to work in some circumstances, but it's still illegal as far as the standard is concerned. Only objects that are truly non-const may be mutated.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top