7

我无法弄清楚为什么我自己会收到此警告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.

代码很简单

#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;
}

任何的想法?

4

6 回答 6

16

source是 a const char *,指向 const 字符的指针,因此不能通过取消引用指针来更改字符(即source[0] = 'A';违反约束)。

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

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

my_strcpy(destination, "Constant String");

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

ptr1[0] = 'A';

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

于 2012-10-22T06:10:56.083 回答
7

你只需要改变:

char *ptr1 = source;

到:

const char *ptr1 = source;
于 2012-10-22T06:11:26.570 回答
2

您指向内存中的同一区域,但也没有限定它const,这是论点。

然后,您允许函数体修改标记为 的那部分内存const

于 2012-10-22T06:08:50.680 回答
1

因为 LHS 的char *类型是 ,而 RHS 的类型是const char *

原因与错误所说的完全一样:

function_prototype_const_modifier.c:13:8: 警告:使用“const char *”类型的表达式初始化“char *”会丢弃限定符

该语句允许您丢弃const限定符,它允许修改指向的字符串ptr1ptr2因此编译器会抱怨。

于 2012-10-22T06:08:46.967 回答
1

您正在将指向字符常量的指针分配给指向 char 的指针。通过这样做,您可能会修改字符

于 2012-10-22T06:08:50.713 回答
0

在这种情况下,我们能做些什么。

感谢@user529758 的明确信息。

只是加上一个答案。

修改的:

#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 = (char*)source;
    char *ptr2 = destination;
    while(*ptr1 != '\0') {
        *ptr2++ = *ptr1++;
    }
    *ptr2 = '\0';
    return destination;
}
于 2014-03-29T03:07:54.600 回答