The following code compiles fine with, for example, the default settings in Xcode 11.3.1:
#include <stdio.h>
int main(int argc, const char * argv[]) {
char* thing = "123";
thing[2] = '4';
printf("%s\n", thing);
return 0;
}
However, at runtime the code traps with EXC_BAD_ACCESS on thing[2] = '4'
. I assume this is because the memory for the bytes representing "123"
is compiled into my program's binary somewhere that on a modern processor/OS gets marked as for code rather than data. (This answer confirms that — not to mention there's a leaq 0x4d(%rip), %rsi ; "123"
line in the disassembly, passing the pointer to an address relative to the instruction pointer!)
Is it just a historical artifact that C allows this, from the era of self-modifying code? I notice that I can also assign void* x = main;
without any complaint that I'm discarding modifiers.
This answer says:
According to the C99 rationale, there were people in the committee who wanted string literals to be modifiable, so the standard does not explicitly forbid it.
Is there any further discussion I could read on that? More practically, is there a way to tell clang and/or gcc to flag such assignments (even though they are not actually forbidden) with a warning, without compiling as C++?