Search code examples
cc-preprocessorvariadic-macros

Casting all parameters passed in MACRO using __VA_ARGS__


I have a macro FOO(...) that receives an unknown number of parameters. I want to cast all those params to uint. Is there a way to achieve it?


Solution

  • Yes, using these utility macros you can apply a macro to each argument(up to 8 for these but they could be expanded for more):

    /* This counts the number of args */
    #define NARGS_SEQ(_1,_2,_3,_4,_5,_6,_7,_8,N,...) N
    #define NARGS(...) NARGS_SEQ(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1)
    
    /* This will let macros expand before concating them */
    #define PRIMITIVE_CAT(x, y) x ## y
    #define CAT(x, y) PRIMITIVE_CAT(x, y)
    
    /* This will call a macro on each argument passed in */
    #define APPLY(macro, ...) CAT(APPLY_, NARGS(__VA_ARGS__))(macro, __VA_ARGS__)
    #define APPLY_1(m, x1) m(x1)
    #define APPLY_2(m, x1, x2) m(x1), m(x2)
    #define APPLY_3(m, x1, x2, x3) m(x1), m(x2), m(x3)
    #define APPLY_4(m, x1, x2, x3, x4) m(x1), m(x2), m(x3), m(x4)
    #define APPLY_5(m, x1, x2, x3, x4, x5) m(x1), m(x2), m(x3), m(x4), m(x5)
    #define APPLY_6(m, x1, x2, x3, x4, x5, x6) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6)
    #define APPLY_7(m, x1, x2, x3, x4, x5, x6, x7) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7)
    #define APPLY_8(m, x1, x2, x3, x4, x5, x6, x7, x8) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7), m(x8)
    

    So now your FOO macro could be defined like this:

    #define FOO_EACH(x) (uint) x
    #define FOO(...) APPLY(FOO_EACH, __VA_ARGS__)
    

    Resulting in this:

    FOO(x, y) // Expands to (uint) x, (uint) y