问题
Compilation of given code sample with gcc/g++ succeeds. There is no error for strchr
call, which obviously assignes const char *
to char *
.
I've found strchr
is declared as char * strchr(const char *, int)
on two different sources pubs.opengroup.org and cplusplus.com
If strchr
is implemented as to cast away constness, then why's that so?
If goal was to provide function which works both on char *
and const char *
strings - it could have been implemented using two different function names.
Can you give more thorough explanation on this.
#include <string.h>
int main () {
const char *str = "Sample string";
char * ptr;
//ptr = str; // Error: discards const qualifier - both on gcc and g++
pch = strchr(str,'S'); // Succeeds in assigning <const char *> to <char *>
*pch = '4'; // Runtime error: segmentation fault
return 0;
}
Tried it on Win7 using MSYS2/mingw-w64 gcc_v5.3.0 and TDM-gcc32 v5.1.0 .
回答1:
When you call strchr
with a char*
you want a char*
back, so that you don't need to do a cast on the result. C doesn't support function overloading, so the same strchr
function is used for searching in a char*
and in a const char*
. It returns a non-const pointer in all cases. If you call it with a const char*
it is basically casting away the const
so it is the callers responsibility to use it safely (e.g. by assigning the result to a const char*
immediately, to avoid any unsafe use of the returned pointer).
If goal was to provide function which works both on char * and const char * strings - it could have been implemented using two different function names.
Yes, it could have been, but it isn't done like that. The original version of C didn't support const
at all, so it was always the programmer's responsibility to avoid trying to modify string literals. If different function names were used then it would have broken existing code that used strchr
safely. It would have slowed the adoption of the new const
keyword if traditional C code like this suddenly stopped compiling:
char arr[] = "foo bar";
*strchr(arr, 'r') = 'z';
The "spirit of C" is that it doesn't try to stop you doing unsafe things, it's your job to write correct code.
In C++ strchr
is overloaded to preserve constness:
char* strchr(char*, int);
const char* strchr(const char*, int);
This means it automatically does the right thing, and it's much harder to accidentally write unsafe code with strchr
.
来源:https://stackoverflow.com/questions/34842263/how-come-c-standard-library-function-strchr-returns-pointer-to-non-const-when