Search code examples
arrayscpointersinitialization

Possible to initialize a pointer from a value in array of pointers?


I basically want to have a list of functions as an array of function pointers; then I'd like to manage both an index variable into this array, and a pointer variable that would accept values from this array. Consider the following C code illustrating this, which compiles fine:

#include <stdio.h>

void func_01() {
    printf("func_01\n");
}
void func_02() {
    printf("func_02\n");
}
void func_03() {
    printf("func_02\n");
}

enum func_choice_e {
    eFUNC01 = 0,
    eFUNC02 = 1,
    eFUNC03 = 2,
#define _NUM_FUNC_CHOICE 3
    NUM_FUNC_CHOICE = _NUM_FUNC_CHOICE,
};
typedef enum func_choice_e func_choice_t;

void* funcs_ptrs[_NUM_FUNC_CHOICE] = {
    &func_01,
    &func_02,
    &func_03,
};

func_choice_t my_func_choice_idx = eFUNC01;
void* my_func_choice_ptr = &func_01;

int main()
{
    my_func_choice_idx = eFUNC02;
    my_func_choice_ptr = funcs_ptrs[my_func_choice_idx];
    printf("Hello World %p\n", my_func_choice_ptr);

    return 0;
}

As the code above shows, within code I can set the pointer variable through the index variable (my_func_choice_ptr = funcs_ptrs[my_func_choice_idx];).

However, I would like to do something similar, also for the initialization - ultimately, I'd want to just initialize the array values and my_func_choice_idx manually first - and then have the pointer automatically be initialized to the corresponding my_func_choice_idxth element in the array; so instead of the working pointer initializer:

void* my_func_choice_ptr = &func_01;

... I've tried these:

//void* my_func_choice_ptr = funcs_ptrs[my_func_choice_idx]; // error: initializer element is not constant
//void* my_func_choice_ptr = funcs_ptrs[eFUNC01]; // error: initializer element is not constant
//void* my_func_choice_ptr = funcs_ptrs[0]; // error: initializer element is not constant

... and as the error messages in the comments hint, none of these work.

I kind of get why funcs_ptrs[my_func_choice_idx] might fail - my_func_choice_idx is after all a variable -- but by the time the compiler got to my_func_choice_ptr = funcs_ptrs[0];, it should already "know" both the address, size, and initial values of funcs_ptrs -> so I don't see why it cannot set my_func_choice_ptr to the first entry of funcs_ptrs?!

So - is there some syntax I can use for initialization, which will allow me to initialize the pointer variable to a given initial value of an entry in the array (similar to the assignment my_func_choice_ptr = funcs_ptrs[my_func_choice_idx]; which works in normal code)?


Solution

  • You are declaring the function pointers wrong. Function pointers are not void* but need to have the proper signature:

    typedef void(*func_ptr)(void);
    

    which you then can use like so:

    const func_ptr funcs_ptrs[_NUM_FUNC_CHOICE] = {
        &func_01,
        &func_02,
        &func_03,
    };
    
    func_choice_t my_func_choice_idx = eFUNC01;
    func_ptr my_func_choice_ptr = funcs_ptrs[eFUNC01];
    

    If you want to initialize it using my_func_choice_idx, you can't do it globally since it's not a constant, but you can do it in main:

    int main(void) {
        func_ptr my_func_choice_ptr = funcs_ptrs[my_func_choice_idx];
    }