【问题标题】:Is function pointer type in _Generic assoc-list not working as expected?_Generic assoc-list 中的函数指针类型是否按预期工作?
【发布时间】:2014-12-08 01:15:35
【问题描述】:

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

【问题讨论】:

    标签: c generics macros types c11


    【解决方案1】:

    您面临的问题是_Generic 的选择表达式没有被评估。如果是这样,您的函数名称将衰减为函数指针,一切都会正常工作。

    &amp; 添加到您的选择表达式应该可以解决这个问题。

    【讨论】:

    • 啊..我以为我试过了——但看起来我没有..愚蠢的我,非常感谢你的回答——是的,它现在正在工作;) (不过我还是要等 8 分钟才能接受你的回答)
    • C11 中的相关引用,6.5.1.1 声明 不评估通用选择的控制表达式。如果泛型选择具有与控制表达式的类型兼容的类型名称的泛型关联,则泛型选择的结果表达式是该泛型关联中的表达式。否则,泛型选择的结果表达式是默认泛型关联中的表达式。不会评估来自任何其他泛型选择的泛型关联的表达式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-12
    • 1970-01-01
    • 2020-12-26
    • 2022-01-04
    • 2014-09-04
    • 1970-01-01
    相关资源
    最近更新 更多