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

时间:2016-01-17 18:52:27

标签: c gcc const strchr

使用gcc / g ++编译给定代码示例成功。 int const b = 0; foo(&b); // the write inside foo causes Undefined Behavior 来电没有错误,明显会将strchr分配给const char *

我发现char *在两个不同来源pubs.opengroup.orgcplusplus.com

上被声明为strchr

如果实施char * strchr(const char *, int)以抛弃常量,那为什么会这样呢?

如果目标是提供适用于strchrchar *字符串的函数 - 它可以使用两个不同的函数名实现。

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

const char *

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

1 个答案:

答案 0 :(得分:9)

当您使用strchr致电char*时,您希望返回char*,这样您就无需对结果进行投射。 C不支持函数重载,因此使用相同的strchr函数在char*const char*中进行搜索。它在所有情况下都返回一个非const指针。如果你使用const char*来调用它,它基本上会丢弃const,因此调用者有责任安全地使用它(例如,通过立即将结果分配给const char*,以避免任何不安全地使用返回的指针)。

  

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

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

char arr[] = "foo bar";
*strchr(arr, 'r') = 'z';

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

在C ++中strchr被重载以保留constness:

char* strchr(char*, int);
const char* strchr(const char*, int);

这意味着它会自动做正确的事情,并且用strchr意外编写不安全的代码要困难得多。