为什么我得到; 使用'const char*'类型的表达式初始化'char*'会丢弃限定符?

mko*_*mko 7 c

我无法弄清楚为什么我自己得到这个警告clang:

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.
Run Code Online (Sandbox Code Playgroud)

代码很简单

#include<stdio.h>

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;
}
Run Code Online (Sandbox Code Playgroud)

任何的想法?

小智 15

source是一个const char *指向const字符的指针,因此不能通过解除引用指针来改变字符(即source[0] = 'A';违反约束).

但是,将其分配给char * 丢弃此约束; 一个简单的char *建议是ptr1指针指向的字符不是常量,你现在可以自由编写ptr1[0] = 'A';而不会出现编译器错误("诊断消息").

考虑传递字符串文字时这意味着什么.由于字符串文字是"只读"(它是a const char []),因此尝试修改其内容是未定义的行为.所以,如果你打电话

my_strcpy(destination, "Constant String");
Run Code Online (Sandbox Code Playgroud)

但是在代码中出于某种原因你写了

ptr1[0] = 'A';
Run Code Online (Sandbox Code Playgroud)

你不会得到编译器诊断消息,因为它ptr1是一个指向非常量字符的指针,但你的程序仍然会调用未定义的行为(实际上,很可能崩溃,因为字符串文字放在只读内存区域).


Pau*_*l R 5

您只需要更改:

char *ptr1 = source;
Run Code Online (Sandbox Code Playgroud)

至:

const char *ptr1 = source;
Run Code Online (Sandbox Code Playgroud)