6

重複の可能性:(
非constへのポインターへのポインター)を(constへのポインターへのポインター)に変換することが合法ではない理由

次のfooの呼び出しで警告(gcc 42.2)が表示されるのはなぜですか?

void foo(const char **str)
{
  (*str)++;  
}

(...)
char **str;
foo(str);
(...)

char **を除いて関数を呼び出せない理由は理解できますconst char **が、その逆は問題ないように思われるので、なぜ次の警告が表示されるのでしょうか。

warning: passing argument 1 of 'foo' from incompatible pointer type
4

1 に答える 1

8

間違っています。仕様でサポートされているため、ここでコンパイラと議論する余地はありません。これが間違っている理由を正確に説明する例です。

void func(const char **p)
{
    *p = "abc";
}

void func2(void)
{
    char *a;
    func(&a);
    *a = 'x';
}

コンパイラがエラーを吐き出さなかった場合、文字列リテラル(メモリ内で読み取り専用とマークされることが多い)を上書きするため、プログラムがクラッシュする可能性があります。

したがって、任意の値から修飾子を削除できるため、暗黙的にキャストchar **することはできません。基本的に、明示的なキャストなしで自由に無視することができます。const char **constconst

コンパイラがエラーではなく警告を出す主な理由は、多くの古いコードがconst、コードが今日書かれた場合のように修飾子を使用しないためです。

于 2012-12-06T15:15:32.923 に答える