4

私が聞いたように、関数へのポインタをに変換することは安全ではありませんvoid*

さて、キャストしても安全ですか

void (*enumerate) (void (*)(const struct foo *event, void *), void *)

void (*enumerate) (void (*)(const void *event, void *), void *)

そしてそれを

void (*)(const void *, void *)最初の引数として、最初のvoid*をstructfoo *として扱いますか?

4

1 に答える 1

7

いいえ、これは安全ではありません。struct foo *aとavoid *が同じサイズとフォーマットであることがC標準によって保証されていません。一般に、関数ポインターを他の関数ポインター型にキャストすることは、災害のレシピです。qsort安全な解決策は、引数以外の引数を処理する比較関数を作成する場合と同じように、引数を正しい型に変換する追加の関数を挿入することですvoid *

static int compare_foo_as_voidp(void const *a, void const *b)
{
    return compare_foo((struct foo const *)a, (struct foo const *)b);
}

(Oli Charlesworthがコメントに書いているように、キャスト自体は問題ではありませんが、ポインターを介して呼び出すとUBが発生します。)

于 2012-06-09T12:22:34.463 に答える