As I heard, It is not safe to convert pointer to function to void*.
Okay, is it safe to cast
void (*enumerate) (void (*)(const struct foo *event, void *), void *)
to
void (*enumerate) (void (*)(const void *event, void *), void *)
and then call it with
void (*)(const void *, void *) as first argument, which treats its first void* as struct foo*?
No, this is not safe. It’s not guaranteed by the C standard that a
struct foo *and avoid *have the same size and format. In general, casting function pointers to other function pointer types is a recipe for disaster. The safe solution is to insert an extra function that converts the arguments to the right type, just as you’d do when writing a comparison function forqsortthat handles non-void *arguments:(As Oli Charlesworth writes in the comment, the cast itself is not the problem, but calling through the pointer causes UB.)