Search code examples
cpointerscastingstructure

Difference between 'void *' and 'void * (*function)(void *)' initialization, casting, and function pointer calls?


More specifically, how do these 3 pointers work in the symbol table and compiler?

My understanding is:

void * object is a pointer to an object or function with an unspecified type which basically requires casting of the object to interpret correctly such as (int)object.

Can casting be done by member/object type as long as the compiler has a valid declaration of type info for that object including storage qualifiers and specifiers in the symbol table?

For example:

void * object;
struct Structure {int member;} Structure;
printf("Object is: %d\n", (Structure->member)(*object));

or in the case of the function:

void * (* function)(void *);

my understanding is that the object names a pointer to a function accepting a pointer to an unknown object or function pointer which returns a pointer to an unknown object or function pointer. Function calling/dereferencing is unclear. Supposedly assignment to a void * object which initializes the declaration of the object is supposed to assume the type it is initialized from.

What is the difference between these function pointer calls?

    struct Structure {void *member;} Structure;
    Structure.member = &main();
    
   /*This assignment, based on my understanding, to Structure.member from main() is supposed to 
    *initialize ember to the type of main() which is assigned automatically or via memcpy()*/

    Structure.member(arg); 
    /*or:*/ 
    Structure.(*(member(arg))); 
    /*or:*/ 
    Structure.(*member(arg))); 

This format then appears to be:

(cast_type) (return_object_type_qualifiers_specifiers)(object_name)(object_parameters);

How does this grouping work?


Solution

  • A void * contains no information about the the type of the object it points to. It's up to the programmer to keep track of it and convert it back to the proper pointer type.

    In this example:

    struct Structure {void *member;} Structure;
    Structure.member = &func;
    

    It's not valid to treat Structure.member as a function because that's not its type. It would need to be cast back to the proper function pointer type before it could be called. So if func is defined as void func(void), you would need to do this:

    ((void (*)(void))Structure.member)();
    

    Also, it's not strictly allowed to convert a function pointer to an object pointer, and a void * is an object pointer, however most implementation you're likely to use will still support it.