c-preprocessor

How to expand param list in C preprocessor


I have this macro:

#define DO_SOMETHING(N, a,b,c,...)

my goal is to write such macro with listsd (eg without ...) that expands to:

DO_SOMETHING(1, a,b,c,...) DO_SOMETHING(2, a,b,c,...) DO_SOMETHING(3, a,b,c,...)

Here's my approach:

#define REP_3(D, A) D(1, A) D(2, A) D(3, A) 
#define GENERATE(a,b,c, ...) REP_3(DO_SOMETHING, (a,b,c,__VA_ARGS__))

however, this expands to:

DO_SOMETHING(1, (a,b,c,...)) DO_SOMETHING(2, (a,b,c,...)) DO_SOMETHING(3, (a,b,c,...))

Perhaps, I need something like:

REP_3(DO_SOMETHING2, (a,b,c,__VA_ARGS__))
#define DO_SOMETHING2(N, A) DO_SOMETHING(N, unroll(A)) //??

How can I unroll that list of args represented by A? In other words, what's DO_SOMETHING2 should be defined to translate N, A, where A is a list of args (a,b,c,...) to N, a,b,c, ...

I could define unroll:

#define unroll(...) __VA_ARGS__
#define DO_SOMETHING2(N, A) DO_SOMETHING(N, unroll A)

but this doesn't work, or works with some changes in msvc, but not with gcc


Solution

  • Sorry, if the question wasn't worded clearly, but the goal was to:

    that is:

    #define REP_3(D, A) D(1, A) D(2, A) D(3, A) 
    #define DO_SOMETHING(N, a,b,c,...)
    #define GENERATE(a,b,c, ...) REP_3(DO_SOMETHING, (a,b,c,__VA_ARGS__))
    

    calling GENERATE(a,b,c,d,e) should expand to:

    DO_SOMETHING(1, a,b,c,d,e) DO_SOMETHING(2, a,b,c,d,e) DO_SOMETHING(3, a,b,c,d,e)
    

    In other words, what GENERATE(a,b,c, ...) should be defined to, without making changes to REP_3 and DO_SOMETHING?

    At first, DO_SOMETHING should be passed as a list arg:

    #define GENERATE(a,b,c, ...) REP_3(CALLFUNC, (DO_SOMETHING,a,b,c,__VA_ARGS__))
    

    Then:

    #define EXPAND(x) x
    #define UNROLL(...)          __VA_ARGS__
    #define CALLFUNC2(N, F, ...) EXPAND(F(N, __VA_ARGS__))
    #define CALLFUNC1(...)       EXPAND(CALLFUNC2(__VA_ARGS__))
    #define CALLFUNC(N, A)       CALLFUNC1(N, UNROLL A)
    

    these multiple hoops through EXPAND are required to get msvc and gcc produce identical results: https://godbolt.org/z/cMxWsox74