12

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?

3
  • Indirection operator * is located before the pointer identifier, like this *a Commented Apr 19, 2014 at 2:13
  • I'm not sure tagging a tag because you are interested in it is good enough reason. You could be interested in specifically C++ for Arduino, but this question would not deserve an Arduino tag. Commented Apr 22, 2016 at 2:26
  • C is (almost) a proper subset of C++, and I was programming in C++ at the time even though the question just focused on the C features of the language. I don't see how me citing core language features relates to you citing a platform external to the language altogether. Commented Apr 24, 2016 at 23:36

5 Answers 5

21

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.

Sign up to request clarification or add additional context in comments.

10 Comments

The second one could create a static array if declared in namespace scope. It's only automatic if in function scope.
@R.MartinhoFernandes updated, thanks (I hope I fixed it)
I initially misread "remove the const" as "remove the const with const_cast", not "remove the const from the declaration". The second is clearly fine while the first is undefined.
@MarkB: The first is not undefined.
@SethCarnegie: That's right. Casting away constness from a valid object never invokes UB; attempting to modify an immutable object (which you can usually only do after having casted away constness) will.
|
7

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.

2 Comments

I suppose in #2 you mean "(...) string literal's immutable array (...)", right?
@R.MartinhoFernandes: Right :)
0

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.

Comments

0

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.

Comments

0

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.