7

一部のCコードをTIDSPチップ環境に移植しています。私はCコンパイラに取り組んでいます。

関数へのポインタを含むデータ構造があります。データ構造を初期化する関数があります。このようなもの:

typedef void (*PFN_FOO)(int x, int y);

struct my_struct
{
    PFN_FOO pfn;
};

init_struct(struct my_struct *p, void *pfn)
{
    p->pfn = (PFN_FOO)pfn;
}

Visual StudioとGCCでは、この種のコードは文句なしにコンパイルされます。実際、pfn引数は型であるためvoid *、キャストを配置する必要はありません。それは文句なしに暗黙のうちにキャストするだけです。

TIDSPチップ用のCodeComposerStudioで、「警告:無効な型変換」が表示されます。

私のポリシーは、警告なしにコードをコンパイルすることなので、これを修正したいと思います。いろいろなキャスティングを試しました。void *ポインタをint最初にキャストしてから正しいタイプにキャストすれば、コンパイラは完全に満足していることがわかりました。うわぁ、うん!

コンパイラが文句を言わずにこのキャストを行うにはどうすればよいですか?intコンパイラをシャットダウンするために本当にキャストする必要がありますか?

注:私は特に、「の代わりに受け入れるように変更する」という効果の解決策を探していません。これは、この単純化されたコードスニペットでは機能しますが、異種のもののリストを作成する実際のコードでは機能しません。init_struct()PFN_FOOvoid *

4

2 に答える 2

13

標準Cは、データオブジェクトへのポインタと関数へのポインタ間の変換を特にサポートしていません。GCCとVisualStudioは、これを拡張機能としてサポートしています。

関数を標準に準拠させたい場合(ただし、void *パラメーターを使用したい場合)は、代わりに関数ポインターにポインターを渡すことができます。これは、関数ポインター自体が通常のオブジェクトであるために機能します。したがって、関数ポインターへのポインターは、適切に変換できますvoid *

init_struct(struct my_struct *p, void *pfn)
{
    PFN_FOO *foo = pfn;
    p->pfn = *foo;
}

次に、呼び出し元はPFN_FOO、呼び出しを行うときにポインタを渡すための一時オブジェクトを作成する必要があります。

PFN_FOO fp = &somefunc;
/* ... */
init_struct(p, &fp);
于 2009-10-12T21:41:17.270 に答える
3

書いてはいけませんか?

typedef void (*PFN_FOO)(int x, int y);

このチュートリアルを参照してください。

于 2009-10-12T20:29:07.813 に答える