I would like to pass a "polymorphic" array of pointers to a function.
I can do the following without warnings:
foo (void* ptr);
bar()
{
int* x;
...
foo(x);
}
gcc apparently automatically casts x
to a (void*)
, which is just dandy.
However, I get a warning when I do the following:
foo (void** ptr);
bar()
{
int** x; // an array of pointers to int arrays
...
foo(x);
}
note: expected ‘void **’ but argument is of type ‘int **’
warning: passing argument 1 of ‘foo’ from incompatible pointer type [enabled by default]
My question is: why is passing an (int*)
as a (void*)
argument not 'incompatible', but (int**)
as a (void**)
argument is?
Since all pointer types are the same size (right? it's been a while since I've used C), I can still do something like:
void mainFunc1(int** arr, int len)
{
//goal is to apply baz to every int array
foo(baz, arr, len);
}
void mainFunc2(double** arr, int len)
{
//goal is to apply baz to every int array
foo(qux, arr, len);
}
// I PROMISE that if I pass in a (int**) as ptr, then funcPtr will interpret its (void*) argument as an (int*)
void foo(funcPtr f, void** ptr, int len)
{
for(int i = 0; i < len; i++)
{
f(ptr[i]);
}
}
void baz(void* x)
{
int* y = (int*)x;
...
}
void qux(void* x)
{
double* y = (double*)x;
...
}
The purpose for all the void pointers is so that I can use a function pointer applied to functions that will (down the stack) have different types of ptr arguments: some will take int
arrays, some will take double
arrays, etc.
void **
" very interesting answer written by H2CO3 – Carmencitaall pointer types are the same size (right? it's been a while since I've used C),
, not always, There have been architectures where pointers to different types have different sizes: Read "Are there are any platforms where pointers to different types have different sizes?" – Carmencitaint *
,double *
is that the pointer cannot be correctly dereferenced without that type information. Same goes for pointers with multiple levels of indirection. Ifvoid **
could take anything, then you could assign along double *
to it and get really weird results when you tried to dereference it. – Prosecute