2009-05-08 11 views
2

これは実際には重要ではない質問ですが、私は関数ポインタを使用しているときにこの警告を受け取っていますが、Cで関数ポインタを使用するときの警告

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

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

tree_destroyLineage(decision_tree, free); 

そして、これは私が"warning: passing argument 2 of 'tree_destroyLineage' from incompatible pointer type"メッセージを取得します。私の最初のhypotheisは、コンパイル時にPointervoid *が同じものであることを知ることができなかったので、全く同じタイプの別の関数を作成して、free()への呼び出しを "再呼び出し"し、ポインタの代わりにvoid *を受け入れる関数ポインタ宣言。どちらのアプローチもまったく同じ場所で私に同じような警告を与えました。

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

+7

ご利用には本当に愚かです。単にvoid *を使用してください。 – Zifre

+0

私は本当に持っていない時間を使ってたくさんの既存のコードを変更しなければならないので、それはまだ変わっていないと言われました。また、一部の評価者はvoid *の使用に対して少し抵抗があるので、私はただ単に '透明性'を取り除いています。 また、GLIBの "gpointer"型はまったく同じもので、void *型のtypedefです。実際には、さらに進んで、 "const void *"に "gconstpointer"を定義します。また、少なくとも私のテストが示すように、これは問題を解決しません。 –

+6

なぜそれは意味ですか?私はそれが愚かであるとは思わない...ポインタが 'void *'として実装され、コードを自然言語に近づけるという事実を隠す。 –

答えて

10

私は自由のような機能のための正しい署名であると信じて:

void (*freefunc)(void*) 

ない

void *dataDestructor(Pointer data) 
+0

ありがとう、これは私が "void *"の代わりにPointerを使い続けても解決します。 JFのポストの後、私は何がうまくいかないかを理解しました。 –

2

はこれを試してみてください:ボイドポインタのためのtypedefを使用して

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

は単なる愚かです。

編集:問題は、かっこなしの*dataDestructor、コンパイラは、voidではなく、void *を返します。かっこは、関数がvoidを返すが、関数へのポインタであることをコンパイラに伝えます。

+0

助けてくれてありがとう。私のオリジナルの投稿で私の返信で述べたように、カスタムの "汎用"コンテナライブラリを構築していたときに、GLIB(GTK + 'base'ライブラリ)からvoid *を "typedeffing"する考えがありました。だから、あなたは彼らを非難し、それらを愚かにすることができます。 =) –

+0

はい、GLibも愚かだと思います:)。 GLibの全体のアイデアには欠陥があります。彼らは基本的にC言語でC++を書こうとしています。 – Zifre

+0

より古い言語のより最近の言語の機能を反論理的なものにしているので、私は言いましたが、GLIBはその仕事をうまくやっています。純粋なCのみを使用するという制約があり、作成するすべてのツリーでハイブリッドグリーディブルートフォースアルゴリズムが果たすことに本当に集中している間に、何千ものリストタイプを実装する時間を費やしているときは、時間は重大な問題です。 –

7

私はあなたのライブラリーについてはよく分からないが、私の自由は、戻り値がない(すなわち、それは無効です)。 voidポインターを返しません。

あなたは第二引数はvoidを返し、引数としてボイドポインタを取る関数へのポインタになりたい場合は、私が何をしたいと考えていることは次のとおりです。

無効(* FN)(void *型)

、あなたが持っているものではありません

のvoid *は、fn(void *型)

+0

ありがとう、これは私に違いを見せてくれました。私のデストラクタ関数はvoidの代わりにvoid *として宣言されていましたが、これが問題を引き起こしていました。 –

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

は次のようになります。ポインタのtypedefの

void tree_destroyLineage(Tree greatest_parent, 
          void (*dataDestructor)(Pointer data)); 
関連する問題