具有不同函数 return 值的函数指针数组(在 C 中)
Array of Function-Pointers with different functions return value (in C)
我看过一些函数指针数组的例子(例如here)
在示例中,我看到数组包含具有相同类型的 return 值的函数(例如,所有 int 或所有 void)。
但我想知道你能不能有一个数组来保存不同类型的函数指针?
下一个代码无法编译:
#include <stdio.h>
void Empty_Funcion()
{
;
}
int funcAdd(int a, int b){
return a+b;
}
int main()
{
int ret = 0;
void *array[5] = {&Empty_Funcion, &funcAdd, &Empty_Funcion, &funcAdd, &Empty_Funcion};
ret = (*array[1])(5,7);
printf("%d\n", ret);
return 0;
}
它说问题出在赋值 ret =... "void value not ignored as it ought to be".
你可以这样做:
ret = ( ( int (*)(int,int) ) array[1] )(5,7);
您需要转换为指向具有正确签名的函数类型的指针。
But I'm wondering can you have an array that holds function-pointers of different types?
如 中所述,您的代码不起作用,因为您的数组打算声明包含 return void
的函数指针,但随后您尝试调用它作为指向 returns int
的函数的指针。这些是不兼容的类型,因此需要显式转换。并且,如 ISO C99 标准第 6.3.2.3/8 节所述,允许将函数指针转换为不同的函数指针类型并再次返回:
A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function whose type is not compatible with the pointed-to type, the behavior is undefined.
也就是说,我认为这样做没有任何意义。函数指针转换是静态转换(编译器已知的转换)而不是动态转换,因此您必须手动跟踪数组中的哪些元素是类型void (*)()
并且属于 int (*)(int, int)
类型。为每个函数指针类型设置一个单独的数组并避免完全转换会更简单。这样做会更不容易出错,因为您不会冒险调用函数指针作为错误类型(这将是 未定义的行为)。
更新:
您已经更改了问题,因此 array
现在是一个 void*
指针数组。请注意,虽然普通指针可以自由转换为 void*
,但对于函数指针来说 不是 (尽管它被认为是许多实现中的常见扩展)。
您的数组未声明为函数指针数组,它被声明为指向 void 的指针数组。
要将数组声明为函数指针数组,您可以这样做:
int (*)(int,int) array[5] = ...
或为了清楚起见:
typedef int (*my_function_pointer_type)(int,int);
my_function_pointer_type array[5] = ...
理论上,您不能调用一个 return 无效的函数并期望它 return 某些东西。这违反了 C 标准。在实践中,如果您这样做,您很可能会得到不可预测的值,但在某些情况下(例如尝试 return 结构)使用某些 ABI 可能会导致崩溃。
最好的方法是将 "dummy" 函数的类型与放入数组的其他函数的类型相匹配。
我看过一些函数指针数组的例子(例如here)
在示例中,我看到数组包含具有相同类型的 return 值的函数(例如,所有 int 或所有 void)。
但我想知道你能不能有一个数组来保存不同类型的函数指针?
下一个代码无法编译:
#include <stdio.h>
void Empty_Funcion()
{
;
}
int funcAdd(int a, int b){
return a+b;
}
int main()
{
int ret = 0;
void *array[5] = {&Empty_Funcion, &funcAdd, &Empty_Funcion, &funcAdd, &Empty_Funcion};
ret = (*array[1])(5,7);
printf("%d\n", ret);
return 0;
}
它说问题出在赋值 ret =... "void value not ignored as it ought to be".
你可以这样做:
ret = ( ( int (*)(int,int) ) array[1] )(5,7);
您需要转换为指向具有正确签名的函数类型的指针。
But I'm wondering can you have an array that holds function-pointers of different types?
如 void
的函数指针,但随后您尝试调用它作为指向 returns int
的函数的指针。这些是不兼容的类型,因此需要显式转换。并且,如 ISO C99 标准第 6.3.2.3/8 节所述,允许将函数指针转换为不同的函数指针类型并再次返回:
A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function whose type is not compatible with the pointed-to type, the behavior is undefined.
也就是说,我认为这样做没有任何意义。函数指针转换是静态转换(编译器已知的转换)而不是动态转换,因此您必须手动跟踪数组中的哪些元素是类型void (*)()
并且属于 int (*)(int, int)
类型。为每个函数指针类型设置一个单独的数组并避免完全转换会更简单。这样做会更不容易出错,因为您不会冒险调用函数指针作为错误类型(这将是 未定义的行为)。
更新:
您已经更改了问题,因此 array
现在是一个 void*
指针数组。请注意,虽然普通指针可以自由转换为 void*
,但对于函数指针来说 不是 (尽管它被认为是许多实现中的常见扩展)。
您的数组未声明为函数指针数组,它被声明为指向 void 的指针数组。
要将数组声明为函数指针数组,您可以这样做:
int (*)(int,int) array[5] = ...
或为了清楚起见:
typedef int (*my_function_pointer_type)(int,int);
my_function_pointer_type array[5] = ...
理论上,您不能调用一个 return 无效的函数并期望它 return 某些东西。这违反了 C 标准。在实践中,如果您这样做,您很可能会得到不可预测的值,但在某些情况下(例如尝试 return 结构)使用某些 ABI 可能会导致崩溃。
最好的方法是将 "dummy" 函数的类型与放入数组的其他函数的类型相匹配。