5

私は有効だと思う何か面白いことに出くわしました。まず:

コンパイラ/バージョン

$ gcc --version
gcc (Debian 4.7.2-5) 4.7.2

コンパイラ オプションと警告メッセージ。

$ gcc -c warn.c -o warn.o
warn.c:11:5: warning: initialization from incompatible pointer type [enabled by default]
warn.c:11:5: warning: (near initialization for ‘foo.exec’) [enabled by default]

「Foo()」が「exec」と互換性がない理由を知りたいです。(うまくいけば明確にするためにコメントを追加しました)

typedef struct Thing
{
    void (*exec)(char *abc);
} Thing;

// ME: I don't mess with this.. I make const, K?
void Foo(const char *abc)
{
    (void) abc;
}

// GCC: LOL, nope! probably u messed up.
Thing foo = { Foo };
4

5 に答える 5

4

const char *と同じではありませんchar *

C標準6.7.5.3から(私が強調):

15 2 つの関数型に互換性を持たせるには、両方で互換性のある戻り値の型を指定する必要があります。さらに、両方が存在する場合、パラメータ型リストは、パラメータの数と省略記号ターミネータの使用において一致する必要があります。対応するパラメータは、互換性のある型を持つ必要があります。[...]

C標準6.7.5.1から(私が強調):

2 2 つのポインター型が互換性を持つためには、両方が同じように修飾され、両方が互換性のある型へのポインターでなければなりません。

注:constqualifier

于 2013-08-27T06:47:09.860 に答える
2

基本的に、あなたの関数void Foo(const char *abc)は、私がnot modify指す変数になると言っています。

しかし、ファンクター int srtuctvoid (*exec)(char *abc)は、私might/mightnot modifyが変数だと言っています。

これは受け入れられません。

于 2013-08-27T06:54:07.673 に答える
0

この方向の単なる割り当ては問題ありません。

char * a = <whatever>;
const char * b = a;

ただし、関数シグネチャでは、ルールは代入よりも厳密です。

于 2013-08-27T06:48:09.320 に答える