Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

void * usage for function formal arguments

Tags:

c

#include<stdio.h>
#include<stdlib.h>

void function(void *i, void *j);

struct mystruct {
    int a;
    int b;
} ;

int main()
{

    int a = 50;

    struct mystruct s ;
    s.a = 100;
    s.b = 200;
    function(&a, &s);


}


void function(void *i, void *j)
{
    printf("Integer is %d\n", *i);
    printf("Struct member 1 is %d\n", j->a);
    printf("Struct member 2 is %d\n", j->b);


}

My code above. On compilation I get the following errors and I understand what I need to do to fix them.

voidstartest.c: In function function:
voidstartest.c:27: warning: dereferencing  void *  pointer
voidstartest.c:27: error: invalid use of void expression
voidstartest.c:28: warning: dereferencing  void *  pointer
voidstartest.c:28: error: request for member  a  in something not a structure or union
voidstartest.c:29: warning: dereferencing  void *  pointer
voidstartest.c:29: error: request for member  b  in something not a structure or union

Here's what I need to do to fix the errors:

printf("Integer is %d\n", *(int*)i);

printf("Struct member 1 is %d\n", ((struct mystruct *)j)->a);

printf("Struct member 2 is %d\n", ((struct mystruct *)j)->b);

Questions:

  1. If I have to fix the errors the way I described above doesn't that mean that I have to know the type of pointers I am sending to the function in advance? I find this to be a very strict requirement. Isn't it?

  2. Some library functions have formal argument as void * also ( like qsort). How doer their implementation know what is the correct type of the pointer so that they can dereference it to work on actual data ( it points to)?

like image 214
Ankur Agarwal Avatar asked Dec 05 '25 10:12

Ankur Agarwal


2 Answers

  1. Yes. Which means you can't write the function in a type agnostic way, and therefore need to rethink your design. When working with void* one usually writes a template function, and asks the user for function pointers to functions that are aware of the type and do basic operations .

  2. Their implementation doesn't. They also ask you for function pointers or size parameters in the same manner I described above.

like image 136
StoryTeller - Unslander Monica Avatar answered Dec 06 '25 23:12

StoryTeller - Unslander Monica


Some library functions have formal argument as void * also ( like qsort). How doer their implementation know what is the correct type of the pointer so that they can dereference it to work on actual data ( it points to)?

Because you also provide a comparison function, which takes two void pointers and returns the result of the comparison:

void qsort(void *base, size_t nmemb, size_t size,
           int(*compar)(const void *, const void *));

In that function you can cast the void pointers to pointers to the actual type of the array elements, and then perform any operation you want

int compare_your_structs(const void *first, const void *second)
{
    const struct mystruct *first_struct = (struct mystruct *)first;
    const struct mystruct *second_struct = (struct mystruct *)second;
    /* sort by the "a" field only */
    return first_struct->a - second_struct->a;
}
like image 20
peppe Avatar answered Dec 07 '25 00:12

peppe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!