First, let me know something. String literals are not necessarily read-only data, but simply so that undefined behavior tries to change them.
It does not have to be broken, it can work fine. But, as undefined behavior, you should not rely on it if you want the code to be executed in another implementation, another version of the same implementation, or even in the next environment.
This can happen from the moment the standards were set (the initial mandate of ANSI / ISO was to codify existing practices, not create a new language). In many implementations, strings will use space to increase efficiency, for example code:
char *good = "successful"; char *bad = "unsuccessful";
as a result of:
good---------+ bad--+ | | | VV | u | n | s | u | c | c | e | s | s | f | u | l | \0 |
Therefore, if you changed one of the characters to good , it would also change bad .
The reason you can do this with something like:
char indifferent[] = "meh";
lies in the fact that although good and bad point to a string literal, this operator actually creates an array of characters large enough to hold "meh" , and then copies the data into it 1 . A copy of the data can be freely changed.
In fact, the justification document C99 explicitly cites this as one of the reasons:
String literals are not subject to modification. This specification allows implementations to exchange copies of strings with identical text, put string literals in read-only memory, and perform certain optimizations.
But no matter why, the standard is perfectly clear on that. From C11 6.4.5 String literals :
7 / It is not known whether these arrays are different if their elements have corresponding values. If the program tries to change such an array, the behavior is undefined.
In the latter case, this is discussed in 6.7.6 Declarators and 6.7.9 Initialisation .
1 Although itβs worth noting that the normal βas ifβ rules apply here (as long as the implementation acts as if it conforms to the standard, it can do what it likes).
In other words, if the implementation may find that you are never trying to modify the data, it may well bypass the copy and use the original.