Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is assigning string literal to mutable char* legal on newer language revisions or just warned against by compilers?

Related to Is it bad to declare a C-style string without const? If so, why? , but that question is about best practise, while mine is more language lawyer. Similar questions have been asked, but for C++ and not C.

I was under impression that code like char* s = "test"; is no longer legal C since the introduction of const keyword in C, which made the literals have type const char* instead of char*. The compiler warnings usually use wording of "deprecated", which implies to me that they only allow it to compile old code.

However, reading https://en.cppreference.com/w/c/language/string_literal.html , const is neither used in any examples, not even mentioned at all on the page. It only says:

String literals are not modifiable [...]. If a program attempts to modify the static array formed by a string literal, the behavior is undefined.

without recommending the obvious const which would make it a compilation error.

Is cppreference incorrect (or incomplete) in this case, or does this deprecation work differently from what I expect?

like image 487
Dominik Kaszewski Avatar asked Oct 15 '25 16:10

Dominik Kaszewski


2 Answers

n3550 seems the latest draft.

6.4.6 String literals

  1. <...> For ordinary string literals, the array elements have type char, and are initialized with the individual bytes of the multibyte character sequence corresponding to the literal encoding (6.2.9). <...>

  2. 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.

Note, array elements are not const char. So, char* s = "test"; is still valid and legal in C and compilers may not reject this code.

like image 194
273K Avatar answered Oct 18 '25 06:10

273K


I was under impression that code like char* s = "test"; is no longer legal C since the introduction of const keyword in C, which made the literals have type const char* instead of char*

No, this is not correct. At the point const was introduced, someone made a really bad decision to keep string literals as type char[] rather than const char[] which makes a whole lot more sense. The reason why is because there was a lot of smelly code in place where the program was writing to string literals and using them for storage. Instead of making a better language they focused on remaining backwards-compatible for the benefit of old skunkware.

C++ recognized that this was nonsense and so string literals in C++ were always const char[], which is a well-known difference between the languages. So maybe that's what confused you, or you are compiling C using a C++ compiler.

From ISO C23 6.4.6:

For character string literals, the array elements have type char, ...

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.

So you can't write to them even though they aren't const because that's explicitly undefined behavior. It is bad practice in C to have pointers to string literals which are not of type const char*.

like image 26
Lundin Avatar answered Oct 18 '25 05:10

Lundin