A compound literal is an lvalue and values of its elements are modifiable. In case of
char* str = (char[]){"Hello World"};
*str = 'B'; // A-Okay!
you are modifying a compound literal which is legal.
C11-§6.5.2.5/4:
If the type name specifies an array of unknown size, the size is determined by the initializer list as specified in 6.7.9, and the type of the compound literal is that of the completed array type. Otherwise (when the type name specifies an object type), the type
of the compound literal is that specified by the type name. In either case, the result is an lvalue.
As it can be seen that the type of compound literal is a complete array type and is lvalue, therefore it is modifiable unlike string literals
Standard also mention that
§6.5.2.5/7:
String literals, and compound literals with const-qualified types, need not designate distinct objects.101
Further it says:
11 EXAMPLE 4 A read-only compound literal can be specified through constructions like:
(const float []){1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6}
12 EXAMPLE 5 The following three expressions have different meanings:
"/tmp/fileXXXXXX"
(char []){"/tmp/fileXXXXXX"}
(const char []){"/tmp/fileXXXXXX"}
The first always has static storage duration and has type array of char
, but need not be modifiable; the last two have automatic storage duration when they occur within the body of a function, and the first of these
two is modifiable.
13 EXAMPLE 6 Like string literals, const-qualified compound literals can be placed into read-only memory and can even be shared. For example,
(const char []){"abc"} == "abc"
might yield 1 if the literals’ storage is shared.
(char[]){"abc"}
is designed to be modifiable. – Neighboring(int){1} = 2;
) - the primary difference between your two snippets is that in the first you have a true string literal, while in the second you initialize a local array with a string literal - you'd have the same behaviour if you just modified the first to readchar str[] = ...
. – Charylstr
with a pointer to it's first character. When I saychar str[] = …
, I initialize a non-modifiable char literal and copy it's content into the arraystr
on the stack. – Neighboringconst
qualifier to explicitly tell the compiler your intened. Note that in C it is the programmer's responsibility not to break this contract. Even for string literals, there is no guarantee a write will not work (and C explicitly allows this as an implementation-extension). So not getting an error does not mean it is defined behaviour. If in doubt, please read the standard. – Idechar str[] = (char[]){"Hello"};
, I actually initialize it twice on the stack. – Neighboring