2012-10-22 57 views
4

我想不通,爲什麼我從clang此警告我自己:爲什麼我得到;用'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<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; 
} 

什麼想法?

回答

12

sourceconst char *,一個指向常量字符,因此該字符不能被取消引用指針被改變(即source[0] = 'A';是違反約束)。

但是,將它分配給char *丟棄這個約束;一個簡單的char *表明ptr1指針指向的字符不是常量,您現在可以自由編寫ptr1[0] = 'A';而不會發生編譯器錯誤(「診斷消息」)。

考慮這是什麼意思,當你傳遞一個字符串文字。由於字符串文字是「只讀」(它是const char []),試圖修改其內容是未定義的行爲。所以,如果你

my_strcpy(destination, "Constant String"); 

,但由於某種原因,你的代碼編寫

ptr1[0] = 'A'; 

,你不會得到一個編譯器的診斷信息,因爲ptr1是一個指向非const字符,但你的程序仍然會調用未定義的行爲(實際上,由於字符串文字被放置在只讀內存區域中,所以很可能會崩潰)。

1

因爲L.H.S的類型是char *,R.H.S的類型是const char *

究其原因,正是因爲有什麼錯誤說:

function_prototype_const_modifier.c:13:8:警告:初始化 '字符*' 類型的 '爲const char *' 的表達式丟棄預選賽

該語句允許您放棄const限定符,它允許通過ptr1ptr2修改尖括的字符串,因此編譯器會抱怨。

+0

我想'const'意味着_pointer_是恆定的,而不是指針對象。我會誤會的。 –

+1

Jan從右到左閱讀(無論如何幫助我)。指向字符常量的指針。 char const *是一個指向字符的指針常量。 –

+0

@JanDvorak「const」關鍵字適用於其右側的術語,如果其右側沒有術語,則僅將「const」關鍵字應用於其左側的術語。 – 2012-10-22 06:12:02

1

您正在將指向字符常量的指針指定給指向char的指針。 通過這樣做你可能會冒險修改字符

1

您指向的是內存中的相同區域,但也沒有將其限定爲const以及參數。

然後,您允許函數體修改標記爲const的那部分內存。

4

你只需要改變:

char *ptr1 = source; 

到:

const char *ptr1 = source; 
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; 
} 
相關問題