我正在尝试“破解”类型系统,方法是不限制函数指针参数接受具有特定类型参数的函数。但是,我仍然想让它类型安全,所以我想我会将这个“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/

10-12 12:54
查看更多