C++ strchr在C++;确保其调用者不会修改作为参数传递的字符串
在C中,strchr的定义如下C++ strchr在C++;确保其调用者不会修改作为参数传递的字符串,c++,c,constants,const-correctness,C++,C,Constants,Const Correctness,在C中,strchr的定义如下 char * strchr(const char *s, int c); 此声明向用户保证strhr不会修改“s”的内容(除非代码使用显式类型转换) 从web上收集到的问题是,当“const”属性返回指针时,该定义会强制转换为“const”属性,因此在“C++”中,这不是“const correct” < C++中的解决方案似乎是具有超载函数 const char * strchr ( const char * str, int character );
char * strchr(const char *s, int c);
此声明向用户保证strhr不会修改“s”的内容(除非代码使用显式类型转换)
从web上收集到的问题是,当“const”属性返回指针时,该定义会强制转换为“const”属性,因此在“C++”中,这不是“const correct”
< C++中的解决方案似乎是具有超载函数
const char * strchr ( const char * str, int character );
char * strchr ( char * str, int character );
虽然这是“const-safe”,但我无法理解第二次声明是如何实现的
char*strhr(char*str,int字符)
向调用者承诺不会修改其参数。它不会做出这样的承诺。相反,它为调用者提供了一种通过返回指针修改字符串的方法。这就是为什么这个版本只能用非const指针调用。 C++版本是正确的,C版本不是因为C可以意外写入这个
const char str[] = "Hello world";
*strchr(str, 'o') = 'O'; // undefined behaviour
还是这个
*strchr("Hello world", 'o') = 'O'; // undefined behaviour
<> p> C++版本在编译时会失败
const char str[] = "Hello world";
*strchr(str, 'o') = 'O'; // error: assignment of read-only location
正如你所看到的,给定一个签名,你不能证明一个任意的函数不会修改指向的数据(更糟糕的是,考虑到一个函数可以<代码> COSTOSTCAST 去掉指针并修改它!)但这不是重载的重点,重点是使意外错误更难产生。
我猜是根据定义,而不是按照惯例。第二个版本是针对非常量字符串的。C++对如何处理<代码> const 有点不同。这些实际上是真实的常量,在C语言中,这只是程序员的承诺;它仍然是一个变量(但可能驻留在只读内存中,因此写操作是未定义的行为)。回忆最初const
在C中不存在,因此C函数是char*strchr(char*s,int C)代码>并且该函数也没有修改s
,但这只是在每个文档中“强制”的,而不是在代码中。(或者在此之前是char*strchr(s,c)
)True。但是,一旦引入了“const”,strchr是否会被修改为“char*strchr(const char*s,int c),以便参数中的“const”不会向调用者证明此函数不会修改其参数。此外,“c”编译器随后会使用它,如果“strchr”的开发人员“碰巧修改了这个(没有显式类型转换)标志作为警告。我理解为什么C++版本是正确的。但我不确定它是否涵盖了在“C”语言的参数“strchr”中添加“const”关键字的所有情况。我理解将“const”添加到strchr的原因之一是向调用方声明strchr永远不会修改传递给它的变量。那么,这是否意味着C++中的这种保证是不可能的。但是第一个参数是“conchchar”。因此它将同时接受常量和非常量指针。您提到的是此函数的常见用法之一。但是它的声明方式清楚地表明了strchr不会修改其参数的意图。@ksrikanth您的问题是“我无法理解第二个声明char*strchr(char*str,int character)如何向调用方保证它不会修改其参数。”第一个参数不是const char*
。