If you, somewhere in your source, have the string literal "Hello", that ends up in your executable as part of the code / data segment. This should be considered read-only at all times, because compilers are at liberty to optimize multiple occurences of the same literal into a single entity. You would have multiple cases of "Hello"
in your source, and multiple pointers pointing to them, but they could all be pointing to the same address.
ISO/IEC 9899 "Programming languages - C", chapter 6.4.5 "String literals", paragraph 6:
It is unspecified whether these arrays are distinct provided their elements have the
appropriate values. If the program attempts to modify such an array, the behavior is
undefined.
Thus, any pointer to such a string literal is to be declared as a pointer to constant contents, to make this clear on the source level:
char const * a = "Hello";
Given this definition, a[0] = 'C';
is not a valid operation: You cannot change a const
value, the compiler would issue an error.
However, in more than one ways it is possible to "trick" the language. For one, you could cast the pointer:
char const * a = "Hello";
char * b = (char *)a;
b[0] = 'C';
As the above snippet from the standard states, this -- while syntactically correct -- is semantically undefined behaviour. It might even work "correctly" on certain platforms (mostly for historical reasons), and actually print "Cello". It might break on others.
Consider what would happen if your executable is burned into a ROM chip, and executed from there...
I said "historical reasons". In the beginning, there was no const
. That is why C defines the type of a string literal as char[]
(no const
).
Note that:
- C++98 does define string literals as being
const
, but allows conversion to char *
.
- C++03 still allows the conversion but deprecates it.
- C++11 no longer allows the conversion without a cast.