Michał Ziobro Michał Ziobro - 1 year ago 44
C Question

C programming: void * argument is it really pointer to anything, can I pass function pointer there

I consider how should I use

void *
correctly (I have some break from C language). As I remember
void *
is used to enable passing any argument to callback function. I know that it is ok to pass something like primitive types
int *
, const
char *
or even collection of values as
struct attributes *
.

I consider whether passing pointer to function as
void *
will be ok.

ex.

typedef void (*callback_t)(void *);
typedef void (*my_custom_callback_t)( /* list of params */ )

void someAPIFunction( /*... */, callback_t callback, void *callback_param);

void standard_callback(void *param) {

((my_custom_callback_t) param) ( /* my params */ );
}


I consider whether having such types it will be correct to pass my_custom_callback as param to standard_callback?

void my_custom_callback(/* list of params */) { }

someAPIFunction( /*...*/, standard_callback, my_custom_callback);

Answer Source

No, you cannot pass function pointer as void *.

6.3.2.3 Pointers

  1. A pointer to void may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.

and

  1. A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function whose type is not compatible with the referenced type, the behavior is undefined.

Notice how there is no mention of possibility to mix object and function pointers. It may seem to work on some system, but it's undefined behaviour and not guaranteed to work.

However, you can create wrapper object and pass address of that:

struct wrapper {
    my_custom_callback_t func;
};

struct wrapper my_wrapper = { my_custom_callback };
someAPIFunction( /*...*/, standard_callback, &my_wrapper); 

Or just pass pointer to function pointer (function pointer variable is object type):

my_custom_callback_t func = my_custom_callback;
someAPIFunction( /*...*/, standard_callback, &func); 
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download