Search code examples
cmacrosfunction-pointersvariadic-macros

C - Variadic macro which expands into set of macro calls on each argument


I want to have a single macro call which takes in multiple function pointers, and each function pointer is called by a second macro which is a function declaration.

I want two macros on the form

#define FUNCTION_DEF(func) extern int func(void);
#define FUNCTION_DEFS(...) (???)

which is called as such

FUNCTION_DEFS(
    myFunc1,
    myFunc2,

    otherFunc1,
    otherFunc2,

    defaultFunc
)

which expands into

FUNCTION_DEF(myFunc1)
FUNCTION_DEF(myFunc2)

FUNCTION_DEF(otherFunc1)
FUNCTION_DEF(otherFunc2)

FUNCTION_DEF(defaultFunc)

In other words, this single call to FUNCTION_DEFS expands into function declarations of all the variadic arguments.

Currently I'm just skipping the first step and calling FUNCTION_DEF on each function pointer, however a solution to this would be great.

Is this possible?

Edit:

Thanks to @Vality for introducing me to X-Macro. I found this post "Real-world use of X-Macros" which was exactly what I needed.


Solution

  • I do not believe what you want precisely is possible using the standard C preprocessor. However a similar solution can be accomplished with X macros.

    To do the equivalent of your code using them you would first define the function list as an X macro:

    #define FUNCTION_LIST_A \
        X(myFunc1) \
        X(myFunc2) \
        X(otherFunc1) \
        X(otherFunc2) \
        X(defaultFunc)
    

    Then to instantiate these functions with a specific macro you would then define the macro to perform on each function:

    #define X(name) FUNCTION_DEF(name)
    FUNCTION_LIST_A
    #undef X
    

    Which will then expand to:

    FUNCTION_DEF(myFunc1)
    FUNCTION_DEF(myFunc2)
    FUNCTION_DEF(otherFunc1)
    FUNCTION_DEF(otherFunc2)
    FUNCTION_DEF(defaultFunc)
    

    Hopefully this is useful and close to what you want. Admittedly the syntax is significantly different but if what you wish to accomplish is to apply a chosen function or macro to a whole list of data (in this case function pointers) this is the most idiomatic way I know of to do so using the c preprocessor.