为什么我得到; 使用’const char *’类型的表达式初始化’char *’会丢弃限定符?
我无法弄清楚为什么我会自己发出警告:
function_prototype_const_modifier.c:13:8: warning: initializing 'char *' with an expression of type 'const char *' discards qualifiers [-Wincompatible-pointer-types] char *ptr1 = source; ^ ~~~~~~ 1 warning generated.
代码非常简单
#include char *my_strcpy(char *destination, const char *source); int main(void) { char str1[] = "this is something"; char str2[] = "123456789123456789"; my_strcpy(str2, str1); puts(str2); return 0; } char *my_strcpy(char *destination, const char *source) { char *ptr1 = source; char *ptr2 = destination; while(*ptr1 != '\0') { *ptr2++ = *ptr1++; } *ptr2 = '\0'; return destination; }
任何的想法?
source
是一个const char *
,一个指向const字符的指针,因此不能通过解除引用指针来改变字符(即source[0] = 'A';
是一个约束违规)。
但是,将其分配给char *
会丢弃此约束; 一个简单的char *
表明ptr1
指针指向的字符不是常量,你现在可以自由地写ptr1[0] = 'A';
没有得到编译器错误(“诊断消息”)。
考虑传递字符串文字时这意味着什么。 由于字符串文字是“只读”(它是一个const char []
),因此尝试修改其内容是未定义的行为。 所以,如果你打电话
my_strcpy(destination, "Constant String");
但是在代码中出于某种原因你写了
ptr1[0] = 'A';
你不会得到编译器诊断消息,因为ptr1
是指向非const字符的指针,但是你的程序仍会调用未定义的行为(实际上,很可能崩溃,因为字符串文字放在只读内存区域)。
你只需要改变:
char *ptr1 = source;
至:
const char *ptr1 = source;
因为LHS的类型是char *
,RHS的类型是const char *
。
原因正如错误所说:
function_prototype_const_modifier.c:13:8:警告:使用’const char *’类型的表达式初始化’char *’会丢弃限定符
该语句允许您丢弃const
限定符,它允许通过ptr1
和ptr2
修改指向的字符串,因此编译器会抱怨。
你指向内存中的相同区域,但不是将它限定为const
,参数是。
然后,您允许函数体修改标记为const
的内存部分。
您正在将指向字符常量的指针指定给指向char的指针。 通过这样做,您可能会冒险修改角色 。
在这种情况下,我们可以做什么。
感谢@ user529758的清晰信息。
只是加上一个答案。
改性:
#include char *my_strcpy(char *destination, const char *source); int main(void) { char str1[] = "this is something"; char str2[] = "123456789123456789"; my_strcpy(str2, str1); puts(str2); return 0; } char *my_strcpy(char *destination, const char *source) { char *ptr1 = (char*)source; char *ptr2 = destination; while(*ptr1 != '\0') { *ptr2++ = *ptr1++; } *ptr2 = '\0'; return destination; }