Following code works fine, however I was wondering if this is valid use of rule that void* is compatible with any other pointer
#include <stdio.h>
typedef struct {
int foo;
} SomeStruct_t;
typedef void(*SomeFunction_t)(void* ptr);
void bar(SomeStruct_t* str) {
printf("%d\n", str->foo);
}
void teddy(void* anyPtr) {
SomeStruct_t* str = (SomeStruct_t*)anyPtr;
printf("%d\n", str->foo);
}
int main()
{
SomeFunction_t functPtr = (SomeFunction_t)bar;
SomeStruct_t data = {.foo = 33};
functPtr(&data);
functPtr = teddy;
functPtr(&data);
return 0;
}
Question is, should I use bar
or teddy
variant? I prefer bar
but I'm not sure if for some corner cases this might lead to hard to detect problem.
This is not valid:
SomeFunction_t functPtr = (SomeFunction_t)bar;
Because you're casing a function pointer of type void (*)(SomeStruct_t*)
to type void (*)(void*)
and subsequently calling it though the casted type. The function pointer types are not compatible because the parameters are not compatible. This triggers undefined behavior .
While a SomeStruct_t *
can be converted to a void *
, that conversion can't happen because the casted function pointer prevents it. There's no guarantee that SomeStruct_t *
and void *
have the same representation.
Using the function teddy
which matches the function pointer type is safe. Also, you don't need to cast the parameter to SomeStruct_t *
inside the function because conversions to/from void *
don't require one in most cases.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.