[英]Why does GCC accept convertion from 'const char *' to 'char *' on std::strrchr() returned value?
[英]Why strrchr() returns `char*` instead of `const char*`?
函数char* strrchr(const char *str, int ch)
返回str
( const char *
)中的指针( char*
),其中ch
的最后一个出现位置。
所以我们可以编写以下代码而不进行任何转换:
#include <string.h>
int main()
{
const char CONSTSTR[] = "foo/bar/foobar.txt";
char *ptr = strrchr (CONSTSTR, '/');
*ptr++ = 'B';
*ptr++ = 'A';
*ptr++ = 'D';
}
返回char*
而不是const char*
什么好处?
编辑:
正如Shafik Yaghmour指出的那样, strchr实现如何运作有很好的答案?
由于我的代码是在C ++中,我将使用<cstring>
而不是<string.h>
。 谢谢你的回答;-)
然而, Mike Seymour的答案最适合这个问题。 我甚至在下面添加了一个更详细的答案来清楚地说明,因为strrchr()
是一个C函数(不允许重载),声明适合const和非const字符串。 因为可以使用非const字符串调用strrchr()
,所以返回的字符串也应该是非const 。
您正在查看C标准库( <string.h>
)中的遗留函数。 C ++库( <cstring>
)引入了适当的const
和非const
重载 ,因此您应该尽可能使用它。
在C中,函数必须像这样,或强迫用户在许多情况下使用狡猾的强制转换:
const
指针,则无法搜索const
字符串; const
指针,则无法使用它来修改非const
字符串。 在C ++中,您应该包含<cstring>
而不是不推荐使用的C-only标头。 这将给你两个const-correct重载,这在C中无法完成:
const char* strchr(const char* s, int c);
char* strchr( char* s, int c);
const char *str
表示strrchr
保证不修改str
。
返回const char *
表示strrchr
禁止修改返回的值。
<string.h>
中的strrchr()
是一个C函数。 由于C不允许函数重载,因此strrchr()
被设计为适合const和非const字符串。
char* strrchr( const char *str, int ch );
可以使用非const字符串调用strrchr()
,因此返回的字符串也应该是非const,如以下示例中所述。
没有编译错误的const上下文:
#include <string.h>
int main()
{
const char CONSTSTR[] = "foo/bar/foobar.txt";
const char *basename = strrchr (CONSTSTR, '/');
// basename points to "foobar.txt"
}
没有编译错误的非const上下文:
#include <string.h>
int main()
{
char nonconst[] = "foo/bar/foobar.txt";
char *basename = strrchr (nonconst, '/');
basename[0] = 'G';
basename[3] = 'D';
// basename points to "GooDar.txt"
}
使用不当也没有编译错误:
#include <string.h>
int main()
{
const char CONSTSTR[] = "foo/bar/foobar.txt";
char *nonconst = strrchr (CONSTSTR, '/');
*nonconst++ = 'B';
*nonconst++ = 'A'; // drawback of the unique declaration:
*nonconst++ = 'D'; // no compilation error
}
const char* strrchr( const char* str, int ch ); //1st
char* strrchr( char* str, int ch ); //2nd
const上下文使用第一个:
#include <cstring>
int main()
{
const char CONSTSTR[] = "foo/bar/foobar.txt";
const char *basename = std::strrchr (CONSTSTR, '/');
// basename points to "foobar.txt"
}
非const上下文使用第二个:
#include <cstring>
int main()
{
char nonconst[] = "foo/bar/foobar.txt";
char *basename = std::strrchr (nonconst, '/');
basename[0] = 'G';
basename[3] = 'D';
// basename points to "GooDar.txt"
}
不良用法应该产生编译错误:
#include <cstring>
int main()
{
const char CONSTSTR[] = "foo/bar/foobar.txt";
char *nonconst = std::strrchr (CONSTSTR, '/');
// Visual C++ v10 (2010)
// error C2440: 'initializing' : cannot convert from 'const char *' to 'char *'
*nonconst++ = 'B';
*nonconst++ = 'A';
*nonconst++ = 'D';
}
但是最后一个示例使用g++ -Wall file.cpp
不会产生任何编译错误。 使用GCC版本4.1.2(RedHat)和4.7.2(MinGW)进行测试 。
为什么要禁止代码修改返回的变量? 请注意, const char *
不是char * const
,你可以在任何情况下修改字符,但是你不能控制返回的值本身,这没有多大意义,因为你可能想要改变它并根据您的目的在不同位置编辑基础字符串。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.