Reputation: 2017
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*?
Upvotes: 4
Views: 318
Reputation: 363487
No, this is not safe. It's not guaranteed by the C standard that a struct foo *
and a void *
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 for qsort
that handles non-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 Charlesworth writes in the comment, the cast itself is not the problem, but calling through the pointer causes UB.)
Upvotes: 7