To test types during compile time, you can use a macro with _Generic
.
I made a prove of concept:
#include <stdio.h>
#define GETTYPE(fp) _Generic \
( \
(fp) \
, char *(*)(char, int) : 1 \
, int *(*)(char, int) : 2 \
, int *(*)(char*, int) : 3 \
, char **(*)(char, int) : 4 \
)
extern char *a(char,int);
extern int *b(char,int);
extern int *c(char*,int);
extern char **d(char,int);
extern char *a1(char,int);
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
printf("type a %i\n",GETTYPE(a));
printf("type b %i\n",GETTYPE(b));
printf("type c %i\n",GETTYPE(c));
printf("type d %i\n",GETTYPE(d));
printf("type a==a1? %i\n",GETTYPE(a)==GETTYPE(a1));
printf("type b==a1? %i\n",GETTYPE(b)==GETTYPE(a1));
printf("type c==a1? %i\n",GETTYPE(c)==GETTYPE(a1));
printf("type d==a1? %i\n",GETTYPE(d)==GETTYPE(a1));
return 0;
}
This GETTYPE
macro converts each listed type to a value. This value can then be used to store the type and compare it. A better version would use a enum
to define the value, but you can do that yourself.
The macro has to be invoked while you still hold the original function pointer (or with the actual function that decays into a function pointer). Why this is should be obvious, but this limits its use cases. If you want to keep the information about the type, you need to assign each type a number and store it along a generic function pointer. When you need the function pointer, you can cast it back to the original type based on the type number.
This requires a lot of handwork, since you need to handle every needed type individually.