Wait, C string literals are not already const? On many platforms, they live in a read-only data section, which is write-protected memory.

They're not const because of backwards compatibility. Const correctness in C is a lot weaker than the way C++ enforces it, letting you implicitly cast it away in a lot of cases.

On all modern platforms I'm familiar with, if you try to modify a string literal, you'll segfault. So while it's not const at the language level, it is very much const at the machine level.

At runtime, yes. But I want to know about errors like this at compile time.

That's not the point though. The point is that it's very unlikely any C written in the past 20 years relies on the ability to modify string literals.

Not only that, but there are no valid C programs written ever, which rely on the ability to modify string literals. Doing so is undefined behavior, so the program is not valid. It may happen to work on some random platform, but it's still undefined.

You're young. On all the legacy platforms I'm familiar with, you can modify string literals. That's original c.

I guess you missed the word "modern"? Or are you saying you actually know of one?

Microcontrollers running code loaded in RAM will have rodata linked into that RAM. Just takes an accidental cast to start writing them.

True. All the more reason to make it an error, IMHO.

Sure, choose any platform before 1990. The modern ansi / iso c didn't exist before 1990. The c language is from 1970's. So code from any old tarball will assume c literals are writable, and will crash if not. It's a common complain when compiling old code, google it. The c standard library is full of functions that assume strings are writable: mktemp() sscanf() strtok() etc.

Quote from gcc manual, explaining why you need to compile old code with -writable-strings option: "you cannot call mktemp with a string constant argument. The function mktemp always alters the string its argument points to.

Another consequence is that sscanf does not work on some systems when passed a string constant as its format control string or input. This is because sscanf incorrectly tries to write into the string constant. Likewise fscanf and scanf."

I define "modern" as ANSI/ISO C. That's pretty conservative IMO, I know people who call pre-C99 "legacy C"...

Strings including string literals are supposed to be writable for strtok() to work. Const char * is a modern c construct. You gotta deprecate parts of the standard c library, which will break backward compatibility...

Using strtok on a string literal has been undefined behavior since ANSI C 89.

The standard C library uses const char * almost everywhere where a string is accepted that will not be modified.

I have a strtok() clone for this purpose that returns a pointer range for each token, leaving the string untouched.

But then you have to copy out those pieces in order to have them null terminated so they can correctly function as strings.

The issue is that "const" didn't exist in the earliest forms of C... and even when it became available not everybody started using it.

So you might have a function that doesn't have proper "const" qualifications in its prototype like:

  void my_log(char *message);
and then call-sites like:

  my_log("Hello, World!");
...and that needed to stay compiling.

Some C projects have been ready for this for years due to supporting being compiled as C++.

Doesn’t the first paragraph address this?