简体   繁体   English

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

[英]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. 使用gcc / g ++编译给定的代码示例成功。 There is no error for strchr call, which obviously assignes const char * to char * . strchr调用没有错误,这显然将const char *赋予char *

I've found strchr is declared as char * strchr(const char *, int) on two different sources pubs.opengroup.org and cplusplus.com 我发现strchr在两个不同的源pubs.opengroup.orgcplusplus.com上声明为char * strchr(const char *, int)

If strchr is implemented as to cast away constness, then why's that so? 如果strchr被实现为抛弃strchr ,那为什么会这样呢?

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. 如果目标是提供对char *const char *字符串都起作用的函数 - 它可以使用两个不同的函数名实现。

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 . 使用MSYS2 / mingw-w64 gcc_v5.3.0和TDM-gcc32 v5.1.0在Win7上尝试使用它。

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. 当你使用char*调用strchr ,你想要一个char* ,这样你就不需要对结果进行strchr了。 C doesn't support function overloading, so the same strchr function is used for searching in a char* and in a const char* . C不支持函数重载,因此使用相同的strchr函数在char*const char*进行搜索。 It returns a non-const pointer in all cases. 它在所有情况下都返回一个非const指针。 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). 如果你用const char*调用它,它基本上抛弃了const因此调用者有责任安全地使用它(例如,通过立即将结果赋值给const char* ,以避免任何不安全的使用返回的指针)。

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

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. C的原始版本根本不支持const ,因此程序员始终有责任避免尝试修改字符串文字。 If different function names were used then it would have broken existing code that used strchr safely. 如果使用了不同的函数名,那么它将破坏安全使用strchr现有代码。 It would have slowed the adoption of the new const keyword if traditional C code like this suddenly stopped compiling: 如果像这样的传统C代码突然停止编译,它会减慢新const关键字的采用速度:

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. “C的精神”是它不会试图阻止你做不安全的事情,编写正确的代码是你的工作。

In C++ strchr is overloaded to preserve constness: 在C ++中, strchr被重载以保留strchr

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 . 这意味着它会自动执行正确的操作,并且使用strchr意外编写不安全的代码要困难strchr

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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