当给定`const char*`作为第一个参数时,C标准库函数`strchr`如何返回指向非const的指针?

MKP*_*KPS 5 c gcc const strchr

使用gcc/g ++编译给定的代码示例成功.strchr呼叫没有错误,这显然是指定const char *char *.

我发现它strchr被声明为char * strchr(const char *, int)两个不同的来源pubs.opengroup.orgcplusplus.com

如果strchr实现为抛弃constness,那为什么会这样呢?

如果目标是提供兼容char *const char *字符串的功能 - 它可以使用两个不同的函数名实现.

你能否对此作出更全面的解释?

#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;
}
Run Code Online (Sandbox Code Playgroud)

使用MSYS2/mingw-w64 gcc_v5.3.0和TDM-gcc32 v5.1.0在Win7上尝试使用它.

Jon*_*ely 10

当你打电话strchrchar*你想要一个char*后背,这样你就不需要对结果进行强制转换.C不支持函数重载,因此使用相同的strchr函数在a char*和a中搜索const char*.它在所有情况下都返回一个非const指针.如果你用const char*它来调用它基本上就是抛弃const它,那么调用者有责任安全地使用它(例如通过const char*立即分配结果,以避免任何不安全的使用返回的指针).

如果目标是提供对char*和const char*字符串都起作用的函数 - 它可以使用两个不同的函数名实现.

是的,它可能是,但它没有这样做.C的原始版本根本不支持const,因此程序员始终有责任避免尝试修改字符串文字.如果使用了不同的函数名称,那么它将破坏strchr安全使用的现有代码.const如果像这样的传统C代码突然停止编译,它会减慢新关键字的采用速度:

char arr[] = "foo bar";
*strchr(arr, 'r') = 'z';
Run Code Online (Sandbox Code Playgroud)

"C的精神"是它不会试图阻止你做不安全的事情,编写正确的代码是你的工作.

在C++ strchr中重载以保持constness:

char* strchr(char*, int);
const char* strchr(const char*, int);
Run Code Online (Sandbox Code Playgroud)

这意味着它会自动执行正确的操作,并且更难以意外地编写不安全的代码strchr.