使用不同指针类型作为参数来转换函数指针

我认为以下代码描述了我想要做的事情。 具体来说,我希望将一个函数指针强制转换为generics函数类型,唯一的区别在于签名是不同的指针类型。

现在,我知道要求函数指针兼容,如本问题所述 ,但我不确定是否有不同指针类型的参数满足兼容性要求。

代码编译并运行,但是,正如预期的那样,从不兼容的指针类型给出有关赋值的警告。 有没有办法满足编译器并实现我的目标?

#include  int float_function(float *array, int length) { int i; for(i=0; i<length; i++){ printf("%f\n", array[i]); } } int double_function(double *array, int length) { int i; for(i=0; i<length; i++){ printf("%f\n", array[i]); } } int main() { float a[5] = {0.0, 1.0, 2.0, 3.0, 4.0}; double b[5] = {0.0, 1.0, 2.0, 3.0, 4.0}; int (*generic_function)(void*, int) = NULL; generic_function = &float_function; generic_function(a, 5); generic_function = &double_function; generic_function(b, 5); return 0; } 

最干净的方式是恕我直言,在function执行演员。 这将强制所有函数签名相同,并使演员表不受调用者代码的影响。 (这是例如qsort()想要它的方式)

 int double_function(void *p, unsigned size) { double *array = p unsigned uu; for(uu=0; uu < size; uu++){ printf("%f\n", array[uu]); } return 42; } 

是的,在没有原型的情况下宣布它。

 int (*generic_function)() = NULL; 

现在您可以分配任何返回int函数,但也可以传递任何参数,并且编译器不需要拒绝不兼容的参数。

编辑:正如@Mat指出的那样,为了遵循C规范,你需要在调用之前将函数指针强制转换回原始类型,这会使整个练习的function变得非常有用。

 ((int(*)(float*,int))generic_function)(a, 5); 

另一个解决方案(受@wildplasser的回答启发)是将函数包含在函数中,取无效*并在该参数上执行强制转换。 “通过宏”这样做很简单;

 #define WRAP(FN, TYPE) int FN##_wrapped(void* p, int len) { return FN((TYPE*)p, len); } WRAP(float_function, float) WRAP(double_function, double) 

然后你可以使用以下相当简洁的线条;

 generic_function = float_function_wrapped; generic_function(a, 5); 

也就是说,指针转换通常不是我提倡的解决方案,但它有其用例。