我正在尝试“破解”类型系统,方法是不限制函数指针参数接受具有特定类型参数的函数。但是,我仍然想让它类型安全,所以我想我会将这个“hack”与 _Generic
关键字的可能性结合起来。
我有以下四个功能:
#include <stdio.h> /* printf() */
#include <stdlib.h> /* EXIT_SUCCESS */
static void
function_i(int *i)
{
printf("%d\n", *i);
}
static void
function_f(float *f)
{
printf("%.2ff\n", *f);
}
static void
caller(void(*func)(),
void *arg)
{
func(arg);
}
static void
except(void(*func)(),
void *arg)
{
printf("unsupported type\n");
}
第一个和第二个将传递给第三个,我想确定,如果函数的类型和传递给第三个的参数不正确,那么将调用第四个函数。因此我创建了以下
_Generic
选择器:#define handler(func, arg) _Generic((func), \
void(*)(int*): _Generic((arg), \
int* : caller, \
default : except), \
void(*)(float*): _Generic((arg), \
float* : caller, \
default : except), \
default: except)(func, arg)
然后我调用他们:
int main(void)
{
int i = 12;
float f = 3.14f;
void(*func_ptr_i)(int*) = function_i;
void(*func_ptr_f)(float*) = function_f;
handler(function_i, &i);
handler(function_f, &f);
handler(func_ptr_i, &i);
handler(func_ptr_f, &f);
return EXIT_SUCCESS;
}
输出非常有趣:
unsupported type
unsupported type
12
3.14f
我希望这也适用于前两种情况,而无需为传递的函数创建特定的函数指针变量。问题是:这是 clang 的
_Generic
中的实现错误,还是预期的行为?是吗,我很好奇到底是为什么?以及如何在不创建额外函数指针的情况下使其工作?提前致谢!
系统信息:
compiler: Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
flags: cc -std=c11 -Wall -v -g
最佳答案
您面临的问题是未评估 _Generic
的选择表达式。如果是这样,您的函数名称将衰减为函数指针,并且一切正常。
将 &
添加到您的选择表达式应该可以解决这个问题。
关于c - _Generic assoc-list 中的函数指针类型是否未按预期工作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26340574/