Readit News logoReadit News
jcalvinowens · 5 months ago
Modifying string litetals has never worked on any platform I've run code on the past 20 years. They're always in .rodata. I can't imagine doing this by default would be a problem except for really old code.
_kst_ · 5 months ago
The C standard, since 1989, has said that attempting to modify the array object corresponding to a string literal has undefined behavior. Whether it "works" or not is not the issue.

The problem is that it's currently legal to pass a string literal to a function expecting a (non-const) pointer-to-char argument. As long as the function doesn't try to write through the pointer, there's no undefined behavior. (If the function does try to write through the pointer, the behavior is undefined, but no compile-time diagnostic is required.) If a future version of C made string literals const, such a program would become invalid (a constraint violation requiring a diagnostic). Such code was common in pre-ANSI C, before const was introduced to the language.

The following is currently valid C. The corresponding C++ code would be invalid. The proposal would make it invalid in C, with the cost of breaking some existing code, and the advantage of catching certain errors at compile time.

    #include <stdio.h>

    void print_message(char *message) {
        puts(message);
        // *message = '\0'; // would have undefined behavior
    }

    int main(void) {
        print_message("hello");
    }

jcalvinowens · 5 months ago
> Whether it "works" or not is not the issue.

Of course it is. It doesn't work on anything modern, and thus it is impossible for portable code which actually runs in the real world and has to work to have relied on it for a long time.

Your example is not code any competent C programmer would ever write, IMHO. Every proficient C programmer I've ever worked with used "const char *" for string literals, and called out anybody who didn't in review.

Old code already needs special flags to build with modern compilers: I think the benefit of doing this outweighs the cost of editing some makefiles.

zabzonk · 5 months ago
Yes, but C (or C++, for that matter) has no concept of .rodata. This is something that needs to be enforced by the compiler, as it is in C++, and why C programmers should probably simply use a C++ compiler, with its much stronger type checking.
jcalvinowens · 5 months ago
You missed the point: I'm saying it has been impossible to modify string literals forever, so enforcing const is probably a non-issue except in very old C.
kazinator · 5 months ago
If you suddenly make string literals const char, tons of previously correct code will require diagnostics. Code which requires diagnostics is incorrect and has undefined behavior if it is translated and executed anyway.

C++ went through this over 20 years ago. I can't remember if it was already in c++03 or whether it was a post '03 draft feature.

hun3 · 5 months ago
The affected platforms lack an OS (e.g., bootloaders) and/or an MMU/MPU (e.g., microprocessors like AVR)
jcalvinowens · 5 months ago
I don't care about platform specific stuff. I'm talking about C which is actually intended to be portable. Nothing written with portability in mind in the past ~decade is going to be doing this.
Dwedit · 5 months ago
Wait, C string literals are not already const? On many platforms, they live in a read-only data section, which is write-protected memory.
HeliumHydride · 5 months ago
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.
jcalvinowens · 5 months ago
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.
dyhi55 · 5 months ago
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...
kazinator · 5 months ago
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.

kevin_thibedeau · 5 months ago
I have a strtok() clone for this purpose that returns a pointer range for each token, leaving the string untouched.
bodyfour · 5 months ago
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.

kazinator · 5 months ago
Some C projects have been ready for this for years due to supporting being compiled as C++.
iknowstuff · 5 months ago
Doesn’t the first paragraph address this?

Dead Comment