Making strings constant was something added way back in C90.
Back then, there was still a lot of code which didn't use const properly, so you didn't get a warning.
So as a special case, you don't get a warning when you lose the const-ness of a char pointer.
Compare with this.
Code:
const int a[] = { 1 };
int *b = a;
$ gcc main.c
main.c: In function ‘main’:
main.c:5:12: warning: initialization discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
int *b = a;
However, you can beef up your gcc like so, and get a warning when you do silly things with your string constants.
Code:
$ gcc -Wwrite-strings main.c
main.c: In function ‘main’:
main.c:4:21: warning: initialization discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
char* my_string = "oello world";
^
> Why does it give a segmentation fault and not an error caused by trying to modify 'char const'?
Because regardless of what your compiler says (or not), or your decision to ignore warnings (or not), the OS always has the last word on whether a particular memory access is valid.
> Also, is it possible to identify whether a char* passed into a function is a string literal or malloced?
No.
Sure, there are a multitude of hacks on a per case basis, but nothing clean simple and portable.