2

これは実際には重要ではない質問ですが、ほとんどの場合、関数ポインターを使用してこの警告を受け取りますが、それでも自分で理由を理解できませんでした。次のプロトタイプを検討してください。

typedef void * Pointer;
void tree_destroyLineage(Tree greatest_parent, void *dataDestructor(Pointer data));

これまでのところ、1,000 行のコードをコンパイルしても、警告はゼロです。だから私は宣言を正しく書いたと仮定しています。しかし、ツリー ノードに格納されているデータは単純な構造体であるため、デストラクタとして free を渡してコードで呼び出します。

tree_destroyLineage(decision_tree, free);

そして、これは私に"warning: passing argument 2 of 'tree_destroyLineage' from incompatible pointer type"メッセージを受け取ります。私の最初の仮説は、コンパイラーがコンパイル時にPointervoid *が同じものであることを理解できなかったというものでした。そのため、呼び出しを「再渡す」関数ポインターとまったく同じタイプの別の関数を作成し、関数ポインターをfree()変更してみました。 void *Pointer の代わりに aを受け入れる宣言。どちらのアプローチでも、まったく同じ場所でまったく同じ警告が表示されました。

私は何を間違っていますか、どうすれば解決できますか?

4

4 に答える 4

10

free のような関数の正しい署名は次のとおりだと思います。

void (*freefunc)(void*)

いいえ

void *dataDestructor(Pointer data)
于 2009-05-08T19:12:29.043 に答える
7

ライブラリについてはわかりませんが、私の free には戻り値がありません (つまり、無効です)。void ポインターを返しません。

2 番目の引数を void を返し、引数として void ポインターを取る関数へのポインターにしたい場合は、次のようにします。

ボイド (*fn)(ボイド*)

そしてそうではない

ボイド *fn(ボイド*)

それはあなたが持っているものです。

于 2009-05-08T19:14:13.953 に答える
4
void tree_destroyLineage(Tree greatest_parent, 
                          void *dataDestructor(Pointer data));

次のようにする必要があります。

void tree_destroyLineage(Tree greatest_parent, 
                          void (*dataDestructor)(Pointer data));
于 2009-05-08T19:15:58.533 に答える
2

これを試して:

void tree_destroyLineage(Tree greatest_parent, void (*dataDestructor)(void *data));

void ポインターに aを使用するのtypedefは、単純にばかげています。

編集: 問題は、 の周りに括弧がないと、コンパイラは関数がではなく を*dataDestructor返すと考えることです。括弧は、関数が を返すことをコンパイラに伝えますが、関数へのポインターです。void *voidvoid

于 2009-05-08T19:12:04.253 に答える