No, this is not safe. It is not guaranteed by the C standard that struct foo * and void * have the same size and format. In general, cast function pointers to other types of function pointers are a recipe for disaster. A safe solution is to insert an additional function that converts the arguments to the desired type, as when writing a comparison function for qsort that processes void * arguments:
static int compare_foo_as_voidp(void const *a, void const *b) { return compare_foo((struct foo const *)a, (struct foo const *)b); }
(As Oli Charlworth writes in a comment, broadcasting itself is not a problem, but calling through a pointer calls UB.)
source share