#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:
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?
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)?
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 .
Their implementation doesn't. They also ask you for function pointers or size parameters in the same manner I described above.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With