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

sourceconst char *const 文字へのポインターであるため、ポインターを逆参照して文字を変更することはできません (つまりsource[0] = 'A';、制約違反です)。

ただし、これを に割り当てると、この制約がchar * 破棄されます。簡単なchar *ことは、ptr1ポインターが指す文字が一定ではptr1[0] = 'A';なく、コンパイラ エラー (「診断メッセージ」) を発生させることなく自由に書き込むことができることを示しています。

文字列リテラルを渡すときにこれが何を意味するかを考えてみましょう。文字列リテラルは「読み取り専用」( const char []) であるため、その内容を変更しようとすると未定義の動作になります。だから電話したら

my_strcpy(destination, "Constant String");

しかし、何らかの理由であなたが書くコードで

ptr1[0] = 'A';

は const 以外の文字へのポインターであるため、コンパイラの診断メッセージは表示されません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 に答える