Search code examples
cparametersfunction-pointers

C Function pointers with parameter at declaration/ compile time


Suppose we have a list of events (int) and actions (function pointers), as in:

typedef struct action_type {
    int event;
    int (*func)();
} action_type;

action_type actions[] = {
    { my_event1, my_action1 },
    { my_event2, my_action2 },
    { my_event3, my_action3 },
    { my_event4, my_action1 }
}

and i want to add conditions to actually running the action as part of the table, for

  • better readability and
  • simplification of the action functions.
action_type actions[] = {
    { my_event1, exceeds(&temperature, 100)   , my_action1 },
    { my_event1, between(&temperature, 50, 80), my_action2 },
    ...
}

is there a way to get a notation like this?

Or would I need to create something like:

action_type actions[] = {
    { my_event1, $temperature, exceeds, 100, my_action1 },
    ...
}

However, this approach allows only a fixed number of parameters with a fixed type. As I am writing a library and conditions could be pretty much anything, I am looking for a way to allow different variable types and different parameter counts for the condition() function.


Edit: Added additional info on the conditions possibly having different numbers and types of parameters.


Solution

  • I'd use an X_MACRO, ie: something like this:

    #define MY_EVENT_1 1
    #define MY_EVENT_2 2
    #define MY_EVENT_3 3
    
    static int my_action1(void) { printf("Over 100!\n"); return 0; }
    static int my_action2(void) { printf("Over 120!\n"); return 0; }
    static int my_action3(void) { printf("Over 160!\n"); return 0; }
    
    static int exceeds(int *val, int temp) { return *val > temp; }
    
    typedef struct action_type {
       int event;
       int (*func)();
    } action_type;
    
    #define X_ACTIONS \
        X(MY_EVENT_1, exceeds(&temperature, 100), my_action1) \
        X(MY_EVENT_2, exceeds(&temperature, 120), my_action2) \
        X(MY_EVENT_3, exceeds(&temperature, 160), my_action3)
    
    static action_type actions[] = {
    #define X(type, cond, cb)  { type, cb },
        X_ACTIONS
    #undef X
    };
    
    int main() {
        int temperature = 130;
    #define X(type, cond, cb) if (cond) cb();
        X_ACTIONS
    #undef X
        return 0;
    }