私が関数を持っているとしましょう
void myFun(int*)
C ++では、次の意味は正確には何ですか
( void(*)(void*) )&myFun
(void*)
を引数として取り、?を返す関数へのポインタvoid
ですか?このタイプのキャストは許可されていますか?
私が関数を持っているとしましょう
void myFun(int*)
C ++では、次の意味は正確には何ですか
( void(*)(void*) )&myFun
(void*)
を引数として取り、?を返す関数へのポインタvoid
ですか?このタイプのキャストは許可されていますか?
現状では、それは許可されていないだけだと確信しています。
イニシャルの周りのパレンを削除すると、次のvoid
ようになります。
void (*)(void *)
...そうです、それはvoidを返し、voidへのポインタを唯一の引数として取る関数へのポインタです。そのタイプにキャストするには、タイプの名前全体を括弧で囲む必要があります。(void (*)(void *))
これにより、次のようになります。これにキャストされる値が続き、次のようになります。
(void (*)(void *))&myFun;
少なくともメモリが機能する場合は、はい、これは許可されますが、結果を介してポインタを逆参照する(つまり、ポインタが指す関数を呼び出そうとする)と、未定義の動作が発生する可能性があります。特に、関数を呼び出すと、intへのポインターが必要になり、(おそらく)それが指すものはすべてintとして使用されます。ただし、それが指しているものがintとして使用されるように適切に整列されていない場合、期待どおりに機能しない可能性があります。
キャストは5.2.10(6)で許可されています。
関数ポインタは、異なるタイプの関数ポインタに明示的に変換できます。関数の定義で使用される型と同じではない関数型(8.3.5)へのポインターを介して関数を呼び出す効果は定義されていません。タイプ「pointertoT1」のprvalueをタイプ「pointertoT2」(T1とT2は関数型)に変換して元のタイプに戻すことを除いて、元のポインター値が生成されます。このようなポインター変換の結果は指定されていません。 。
これは、C 6.3.2.3(8)と同等です。
あるタイプの関数へのポインターは、別のタイプの関数へのポインターに変換され、また元に戻される場合があります。結果は元のポインタと同じになります。変換されたポインターを使用して、指定された型と互換性のない型の関数を呼び出す場合、動作は定義されていません。
実際には、異なるが互換性のある引数型(特にポインタ型)を使用した関数ポインタを介した呼び出しは通常成功し、引数に対するCスタイルのキャストの効果があります。ただし、これは決して保証されません。https://stackoverflow.com/a/189126/567292は、gccがそのような未定義の関数ポインタキャスト呼び出しを行うことを決定したケースについて説明していますabort
。