2015-12-23 9 views
6

考えてみましょう:-Wwrite-stringsタイプ-Wwrite-文字列を使用して

char f(const char (*x)[4]); 

void foo(void) { 
    typeof(*"FOO") x[4]; 
    f(&x); 
} 

コンパイル:

gcc-5 -c gcc5.c -Wwrite-strings 

あなたが得る:

gcc5.c: In function ‘foo’: 
gcc5.c:5:7: warning: passing argument 1 of ‘f’ from incompatible pointer type [-Wincompatible-pointer-types] 
    f(&x); 
    ^
gcc5.c:1:6: note: expected ‘const char (*)[4]’ 
    but argument is of type ‘const char (*)[4]’ 
char f(const char (*x)[4]); 
    ^

はバグのように見えます私が何かを逃していない限り、gccで?

注:それは確かにgccのバグだ私にとって

文字列を与え、Cをコンパイルするタイプ定数 "のconstのchar [長さ]"

+1

Cでは '*" FOO "の型は' char'です。 '-Wwrite-strings'はこれを変更する(コンパイラを非標準にする)のですか?そうでなければ、バグは '&x'の型を' const char(*)[4] 'として表示しています:' const'はありません。 –

+1

バグのようです。バグレポートを提出することを検討してください。 – fuz

+1

@PascalCuoq:それでも 'char(*)[4]'は 'const char(*)[4]'に変換可能ですか?なぜそれは "互換性のないポインタ型"ですか? –

答えて

1

-Wwrite-stringsはリテラル文字列の種類を変更します5

gccdocumentationする

-Wwrite-文字列が非const char型へのいずれかのアドレスをコピー*ポインタように型のconst char型[長さ]を定数文字列を与える、

Cをコンパイル言います警告が表示されます。この宣言を持つので

:その後、

typeof(*"FOO") x[4]; 

&x-Wwrite-stringsが存在する場合にはタイプconst char (*)[4]です。標準Cでは&xchar (*)[4]です。

この小さな機能:

void foo(void) { 
    typeof(*"FOO") x[4]; 
    printf("%d\n", __builtin_types_compatible_p(typeof(&x), const char (*)[4])); 
    printf("%d\n", __builtin_types_compatible_p(typeof(&x), char (*)[4])); 
} 

プリント:gcc5.3-Wwrite-strings

1 
0 

。したがって、gcc5.3は、タイプconst char (*)[4]&x-Wwrite-stringsとして正しく識別していることがわかります。

gccは、パラメータを持つ関数を呼び出すときは、引数&xを受け入れる必要があります。互換性のないタイプの警告はIMHOで、gccのバグです。

(このバグはおそらくgccは以前gccのバージョンで-Wwrite-stringsconst char (*)[4]として&xを識別するために)(別のバグを失敗したというだけの理由gccの以前のバージョンでは表示されませんでした。私はgcc4.9.2gcc-6-20151206でテスト。)

関連する問題