Is the type of the function pointer in the _Generic-associated list invalid?

I experimented with "hacking" the type system without restricting a function pointer argument to accept a function with a specific type of arguments. However, I still wanted to make it text-safe, so I decided to combine this "hack" with the keyword capabilities _Generic

.

I have the following four functions:

#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");
}

      

The first and second will be passed to the third, and I want to make sure that if the type of the function and the argument passed to the third are wrong, then the fourth function will be called. So I created the following selector _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)

      

And then I called them:

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;
}

      

The conclusion is very interesting:

unsupported type
unsupported type
12
3.14f

      

I expected this to work for the first two cases too, without the need to create a specific function pointer variable for the passed functions. The question is, is this an implementation bug in clang _Generic

, or is this expected behavior? So, I'm really curious why exactly? And how to make it work without creating additional function pointers?

Thanks in advance!


SYS-INFO:

compiler: Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
flags:    cc -std=c11 -Wall -v -g

      

+3


source to share


1 answer


The problem you are having is that the selection expression is _Generic

not evaluated. If that were the case, your function names would decay to pointer functions and everything would work.



Adding an expression &

to your selection should fix this.

+3


source







All Articles