How to know if a variable is a function pointer in C?

Viewed 263

I have a function of type void(*func)(int) and I get a pointer to this function, how can I know for sure that a pointer is really of this type?

if (typeof(pointer) == void(*func)(int)) {
    //do something     
} 

Is that correct?

edit - I get the pointer from a function as an argument and I want to check the type of the pointer inside this function.

3 Answers

if you are getting your function pointer dynamically , so try to use union to and a flag variable to get it's type without checking something complex

#define type1 1
#define type2 2
union FN
{
void ....
int ....
....
}

typedef struct{
int type;

union FN fn;
} Function;

typeof not a part of the C standard. It is a GNU extension.

If you want to be sure that something is of a particular type, you can handle it at compile-time with _Generic introduced in C11:

_Generic((pointer), 
    void(*)(int): /* insert your code here */,
)

If said pointer is not of type void(*)(int), then it will fail to compile.

If your function gets the pointer as an argument and has this prototype:

void my_function(void (*func)(int)) {
    // How can I test if `func` really points to a function taking an `int`?
}

Then there is not much you can do inside the body of my_function to verify what func really points to.

  • you can test if it is a null pointer:

    if (!func) { /* NULL was passed */ }
    
  • you can test if it points to a known function:

    if (func == exit) { /* haha! (*func)(1) will abort */ }
    
  • beyond the above, it is impossible to tell what was actually passed to my_function: it could be an actual function with the correct prototype, or another function implicitly or explicitly cast to the expected type or even some other scalar object with a cast.

If you want to write a macro whose expansion depends on the type of an expression, you can use the new C11 _Generic construction:

#define IS_VOID_FUNC_OF_INT(func)  _Generic(func, void(*)(int): 1, default: 0)

But using this inside the body of function my_function above will always evaluate to 1: only the defined type of func is tested by _Generic, not that of the original expression used as an argument to the function.

Related