在函数指针中自动转换 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*),然后通过强制转换类型调用它。 函数指针类型不兼容,因为参数不兼容。 这会触发未定义的行为。

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

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

最新更新