函数指针中void*参数的自动转换

以下代码工作正常,但是我想知道这是否有效使用 void* 与任何其他指针兼容的规则

#include <stdio.h>

typedef struct {
    int foo;
} SomeStruct_t;

typedef void(*SomeFunction_t)(void* ptr);

void bar(SomeStruct_t* str) {
    printf("%dn", str->foo);
}

void teddy(void* anyPtr) {
    SomeStruct_t* str = (SomeStruct_t*)anyPtr;
    printf("%dn", str->foo);
}


int main()
{
    SomeFunction_t functPtr = (SomeFunction_t)bar;
    SomeStruct_t data = {.foo = 33};
    functPtr(&data);
    
    functPtr = teddy;
    functPtr(&data);
    return 0;
}

问题是,我应该使用bar还是teddy变体?我更喜欢,bar但我不确定在某些极端情况下这是否会导致难以检测的问题。

回答

这是无效的:

SomeFunction_t functPtr = (SomeFunction_t)bar;

因为您将一个类型void (*)(SomeStruct_t*)为类型的函数指针封装到类型void (*)(void*),然后通过转换类型调用它。函数指针类型不兼容,因为参数不兼容。这会触发未定义的行为。

虽然 aSomeStruct_t *可以转换为 a void *,但这种转换不会发生,因为强制转换的函数指针阻止了它。不能保证SomeStruct_t *void *具有相同的表示。

使用teddy与函数指针类型匹配的函数是安全的。此外,您不需要将参数强制SomeStruct_t *转换到函数内部,因为void *在大多数情况下不需要转换到/从。


以上是函数指针中void*参数的自动转换的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>