CircArgs CircArgs - 1 month ago 7
C Question

C function pointer neither function nor pointer

Before I go on, the closest question to mine I found is :subscripted value is neither array nor pointer function error yet the solution has not applied to mine.

I have a C function with the goal to take in an array of floats and an array of functions, apply each function to the value of the same index in the float array saving the values in an array passed in as an argument.

I was very careful with the syntax and defined a type for function pointers:

typedef float (*func_ptr)(float);


(and if anyone cares to explain im a comment or solution why the syntax is not (does not work as)
typedef float (*)(float) func_ptr
that too would be appreciated)

the function (I think is closest to functioning) in question then looks as:

void Vector_Function(void * _F, float v[], size_t size, float ret[]){
func_ptr (*F)[size]=_F; //trying to cast to pointer to array of function pointers
float (*F)[size]=_F;
for(size_t i=0; i<size; i++){
ret[i]=F[i](v[i]);
}
}


The error is:

> error: called object is not a function or function pointer
> ret[i]=F[i](v[i]);
> ^


What really gets me is that it seems the
typedef
is so blatantly making
F[i]
a function pointer...

Other things I have tried are:

void Vector_Function(void * _F, float v[], size_t size, float ret[]){
float (*F[size])(float)=_F;
for(size_t i=0; i<size; i++){
ret[i]=F[i](v[i]);
}
}

void Vector_Function(float (*F)[size], float v[], size_t size, float ret[]){
//just wrong
for(size_t i=0; i<size; i++){
ret[i]=F[i](v[i]);
}
}

Answer Source

You don't need to include size when you do the cast. If the void* is meant to represent an array of function pointers, then you can cast to an array like so:

void Vector_Function(void * _F, float v[], size_t size, float ret[]){
  func_ptr *funcs = (func_ptr*)(_F);
  for(size_t i=0; i<size; i++){
    func_ptr F = funcs[i];
    ret[i]=F(v[i]);
  }
}

You don't need any indication about the number of things in the array to do the cast, because the array pointer only hold a reference to the start of the array, and there's no information about the size attached to it. This requires that your _F has a certain format, so why not make the type func_ptr* instead of void*?