bassplayer142
bassplayer142

Reputation: 380

Unable to "point to" passed array of function pointers in C

I've been trying to pass an array of function pointers to a function. Once in that function I need a pointer to that array of function pointers but I keep getting an error. I'm able to do it when it isn't a function argument.

void (*(*PointerToFuncPtrArray)[2])(unsigned char data[], unsigned char length);
void (*FuncPtr[2])(unsigned char data[], unsigned char length) = {

    func1,
    func2,
}

void NotArguement(void)  // attempt to point to without passing as parameter
{
    PointerToFuncPtrArray = &FuncP;   // this works
}


//  attempt to pass as argument
void AsArguement((void (*ptr[])(unsigned char data[], unsigned char length))
{
   PointerToFuncPtrArray = &ptr;    // This throws error


}

This throws...

Error   1   error C2440: '=' : cannot convert from 'void (__cdecl **[])(unsigned char [],unsigned char)' to 'void (__cdecl *(*)[2])(unsigned char [],unsigned char)'    

Upvotes: 2

Views: 248

Answers (1)

AnT stands with Russia
AnT stands with Russia

Reputation: 320611

Array declaration in function argument list decays to pointer declaration. So, your function parameter is not declared as an array (despite the misleading appearance). It is declared as a pointer-to-pointer, meaning that inside the function the array type is lost irreversibly.

The same error will be reported in this simple example

int x[2];
...
void foo(int a[2]) /* <- equivalent to `void foo(int *a)` */
{
  int (*p1)[2] = &x; /* <- OK */
  int (*p2)[2] = &a; /* <- ERROR: can't convert `int **` to `int (*)[2]` */
}
...
foo(x);

In the above example a is no longer an array. It is a pointer of int * type, meaning that &a has type int ** and cannot be used to initialize an object of type int (*)[2].

In C, the only way to pass an array to a function while preserving the "arrayness" of the argument is to pass it "by pointer to the whole array", as in

int x[2];
...
void foo(int (*a)[2])
{
  int (*p)[2] = a; /* <- OK */
}
...
foo(&x);

Note that the application of & operator "moved" from inside of the function to the point of the call.

The same modification in your code would look as follows

void AsArguement(void (*(*ptr)[2])(unsigned char data[], unsigned char length))
{
   PointerToFuncPtrArray = ptr;
}

You just have to remember to apply & operator to the array argument when you call this function.

Upvotes: 5

Related Questions