简体   繁体   中英

Auto cast of void* argument in function pointer

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM