Let's say I have a function like:
void myfunc(void* x, void* y){
for(i=0; i<n;i++)
y[i] = x[i]+1;
}
where my goal is to take vector x
, do some math and store it in y
. In this scenario I know x
will be memory allocated as an array of int
s.
I know we can't do math directly on x
as it's cast as void, but I was curious about the most efficient way around this blocker. My current method is to memcpy
x to an int*
temp, do my math, then memcpy
to y
. Obviously this is not a particularly efficient process with multiple memcpy
. I'm sure there is a better way, I just don't know enough about C memory allocation rules to figure it out.
You can avoid the memcpy
. If you wish to work with integers or bytes or whatever other type, then just do the appropriate casting, for example in case x
and y
refer to arrays of int
:
void myfunc(void* x, void* y){
int *xp = x;
int *yp = y;
// By the way, what is n here? Maybe define it somewhere.
for(size_t i = 0; i < n; i++)
yp[i] = xp[i] + 1;
}
And in such case, you don't really need to pass them as void *
at all:
void myfunc(int* x, int* y){
// By the way, what is n here? Maybe define it somewhere.
for(size_t i = 0; i < n; i++)
y[i] = x[i] + 1;
}
In general, void *
is only useful when you do not care about the size and type of objects you are pointing to, or when you need to do generic operations depending on different sizes/types only known at runtime (still, always with appropriate casts).
If you want to allow different types, then you can do something like this:
enum Type { INT, FLOAT, /* ... */ };
void myfunc(void* x, void* y, size_t n, enum Type t) {
switch (t) {
case INT: {
int *xi = x;
int *yi = y;
for(size_t i = 0; i < n; i++)
yi[i] = xi[i] + 1;
break;
}
case FLOAT: {
float *xf = x;
float *yf = y;
for(size_t i = 0; i < n; i++)
yf[i] = xf[i] + 1;
break;
}
// case ...: {
// ...
// }
}
}
Note that this is not really good practice in C though. If you are able to know the type at compile time, then by all means just define different functions taking different types as arguments, it will be the fastest option.