简体   繁体   中英

How come C standard library function `strchr` returns pointer to non-const, when given `const char *` as first argument?

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 .

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 (eg 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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM