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

喜欢而已 提交于 2019-12-23 10:15:31

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!