String literals are lvalues, which leaves the door open to modify string literals.
From C in a Nutshell:
In C source code, a literal is a token that denotes a fixed value, which may be an integer, a floating-point number, a character, or a string. A literal’s type is determined by its value and its notation.
The literals discussed here are different from compound literals, which were introduced in the C99 standard. Compound literals are ordinary modifiable objects, sim‐
ilar to variables.
Although C does not strictly prohibit modifying string literals, you should not attempt to do so. For one
thing, the compiler, treating the string literal as a constant, may place it in read-only
memory, in which case the attempted write operation causes a fault. For another, if
two or more identical string literals are used in the program, the compiler may store
them at the same location, so that modifying one causes unexpected results when
you access another.
From the C Standard (6.4.5 String literals)
7 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.
As for your statement.
The second paragraph says that "C does not strictly prohibit modifying string literals" while compilers do. So should a string literal be modified?
Then compilers do not modify string literals. They may store identical string literals as one array.
As @o11c pointed out in a comment in the Annex J (informative) Portability issues there is written
J.3 Implementation-defined behavior
1 A conforming implementation is required to document its choice of behavior in each of the areas listed in this subclause. The following are implementation-defined:
J.5.5 Writable string literals
1 String literals are modifiable (in which case, identical string literals should denote distinct objects) (6.4.5).