2012-03-04 7 views
4

私は次のコードを持っている:longを関数ポインタにキャストしますか?

long fp = ... 
void (*ptr)(long, char*, char*) = fp; 

長いfpは長いようで来て正しい関数ポインタ、です。私は標準の "キャストなしでintからポインタを作る"という警告を出しています。私はコンパイルすることができます:

-std=iso9899:1990 -pedantic-errors 

この警告はエラーになります。問題は、正しいキャストは何ですか?私は、さまざまな推測を試みている例えば:

void (*ptr)(long, char*, char*) = (void)(*)(long, char*, char*) fp; 

しかし、正しいものを見つけるように見えることはできません。

+0

なぜこれをやりたいですか? –

+0

なぜ私は何をしたいですか? – gubby

+0

整数と関数ポインタの間のキャスト? –

答えて

7

「正しい」のキャストは以下のとおりです。

void (*ptr)(long, char*, char*) = (void (*)(long, char*, char*))fp; 

明らかに、これは、適切な型定義で片付けすることができます。

いずれにしても、結果は実装定義です。可能であれば、これを避けてポインタをポインタ型に維持してください。次善策は、intptr_tがあればそれを使うことです。

+0

@KerrekSB:どのような意味ですか? –

+0

いいえ、気にしないでください、それは問題ありません! –

7

おそらくそれはのようなものです:

void (* ptr)(long, char, char *) = (void (*)(long, char, char *))fp; 

が、私の提案は、typedefを使用し、すべてのこの混乱を忘れることです。

typedef void (* fnPtr)(long, char, char*); 
fnPtr ptr = (fnPtr) fp; 
+0

はい、typedefを使用するのは正しい方法です – slashmais

4

だけ「正しい」やり方がまったくキャストすることではありませんバイナリ表現をコピーする:

long fp; 
void (*ptr)(long, char*, char*); 

memcpy(&ptr, &fp, sizeof ptr); 
+0

sizeof(long)!= sizeof(ptr)のときは大したことはありません。 –

2

ここでの主な問題は、 ANSI-Cは、この機能に依存している無数のC APIにもかかわらず、これを許可していません。したがって、-pedanticでコンパイルすると問題が発生する可能性があります。 他のポスターが暗示していたように、キャストにmemcpy()やユニオンタイプのようなものを使用してキャストの周りを欺くことができます。

ちなみに、POSIXはこれが動作することを保証しているので、 '実装定義の結果'についての部分は非常に怖くなくなりません。

+0

チップをありがとう。 – gubby

+0

C99はこれを明示的に許可しますが、結果が実装定義であることだけを示しています。 –

+0

クール、私はそれを知らなかった。私はたいていC++の人なので、C89にはよく慣れていますが、afmaはそれを許可しませんでした。 – ComicSansMS