Originally Posted by
Eman
it is funny though if the compiler implicitly says char *string is const char *string it should stop me from modifying the values as if i explicitly said it was a const.
It should do it. But unfortunately it doesn't. And the reasons are for historical reasons. That is, an exception. So you can forget about it and assume all string literals are const char.
I will try to repeat what has been pointed out in order to hope bring you clarity.
A string literal in an expressions that starts with a double quote, followed by a series of characters and ends with a double quote. Thus,
"Hello World" is a string literal.
char* s = "Hello World", s is not a string literal, and again, "Hello World" is a string literal.
char s[] = "Hello World", s is not a string literal, and again, "Hello World" is a string literal.
std::string s = "Hello World", s is not a string literal, and again, "Hello World" is a string literal.
std::string s("Hello World"), s is not a string literal, and again, "Hello World" is a string literal.
Now, onto modifying:
Modifying basically means writing a new value to a memory location. It doesn't matter where. You are modifying address X if you are writing to address X.
If something happens to be in that memory location, then you are modifying that something.
If a string literal happens to be occupied a series of memory locations, including X, then you are modifying that string literal.
So...
Code:
const_cast<char*>("Xello World")[0] = 'H';
"Xello World" is a string literal. Its type is out const char[N]. Thus, we cannot modify it. Therefore, we have to remove the const to modify it. That's why we use const_cast. However, note again that we are modifying a string literal here! So this is undefined behavior. You may get a crash. But then again, maybe not. That's the meaning of undefined.
Code:
char* s = "Xello World";
s[0] = 'H';
Again, undefined behavior because s points to a string literal. That means we will try to modify a memory location occupied by the string literal. Hence, this is undefined behavior!
Code:
char s[] = "Xello World";
s[0] = 'H';
Code:
std::string s = "Xello World";
s[0] = 'H';
Code:
std::string s("Xello World");
s[0] = 'H';
In all of these examples, this is not undefined behavior. Let us examine why.
In the first example, the compiler will copy the contents of the string literal into the buffer s. s cannot possibly be a string literal (see above). Therefore, it is safe.
The two last examples are identical, just different syntax. But the point is that a std::string object guarantees that we can modify it. We really don't need to know why, but we shall look into one possible answer to that question anyway.
In one possible implementation, the class could simply create an internal buffer of type char and copy over the string literal. Hence, we would be trying to modify a local buffer that contains the copy of the string literal. This local buffer cannot possibly be a string literal, hence it is safe to modify.