C Language Strings String literals


String literals represent null-terminated, static-duration arrays of char. Because they have static storage duration, a string literal or a pointer to the same underlying array can safely be used in several ways that a pointer to an automatic array cannot. For example, returning a string literal from a function has well-defined behavior:

const char *get_hello() {
    return "Hello, World!";  /* safe */

For historical reasons, the elements of the array corresponding to a string literal are not formally const. Nevertheless, any attempt to modify them has undefined behavior. Typically, a program that attempts to modify the array corresponding to a string literal will crash or otherwise malfunction.

char *foo = "hello";
foo[0] = 'y';  /* Undefined behavior - BAD! */

Where a pointer points to a string literal -- or where it sometimes may do -- it is advisable to declare that pointer's referent const to avoid engaging such undefined behavior accidentally.

const char *foo = "hello";
/* GOOD: can't modify the string pointed to by foo */

On the other hand, a pointer to or into the underlying array of a string literal is not itself inherently special; its value can freely be modified to point to something else:

char *foo = "hello";
foo = "World!"; /* OK - we're just changing what foo points to */

Furthermore, although initializers for char arrays can have the same form as string literals, use of such an initializer does not confer the characteristics of a string literal on the initialized array. The initializer simply designates the length and initial contents of the array. In particular, the elements are modifiable if not explicitly declared const:

char foo[] = "hello";
foo[0] = 'y';  /* OK! */