KAction
KAction

Reputation: 2017

Function pointer conversion in C

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

Answers (1)

Fred Foo
Fred Foo

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

Related Questions