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.
The short answer is: anything that resembles
can be passed in where the parameter declaration is of type void* because void* is generic. However, void** is not. So automatic casting fails.
Because there is no generic pointer-to-pointer type in C.
Reference: C FAQ Question 4.9
Note:
void*
is generic. butvoid**
is not. You can assign address of any type tovoid*
variable butvoid**
can be assigned address ofvoid*
variable only.or
valid but following is an error:
Error: assigning
int**
tovoid**
.Yes you can do like:
For generic array function simply use
void* a
as follows:You better write this function using macros.
Call this function as:
Suppose
int
:Suppose
char
: