Reputation: 12160
I was experimenting with "hacking" the type-system, by not restricting the function pointer argument to accept a function with a specific type of arguments. However, I still wanted to make it type-safe, so I thought I will combine this "hack" with the possibilities of the _Generic
keyword.
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, if the type of the function and the argument passed to the third is not right, then the fourth function will be called. Therefore I created the following _Generic
selector:
#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 output is very interesting:
unsupported type
unsupported type
12
3.14f
I expected this to work for the first two cases as well, without the need to create a specific function pointer variable for the passed functions. The question is: is this an implementation error in clang's _Generic
, or this is the expected behavior? Is so, I'm very curious about why exactly? And how to make it work without creating extra 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
Upvotes: 3
Views: 448
Reputation: 78923
The problem that you are facing is that the choice expression of _Generic
is not evaluated. If it would be, your function names would decay to function pointers and everything would work.
Adding a &
to your choice expression should fix that.
Upvotes: 3