Зацикливание значений макроса Варгара

Если я определяю макрос:

#define foo(args...) ({/*do something*/}) 

Есть ли какой-то способ фактически прокрутить args а не передавать его другой функции? Что-то вроде

 #define foo(args...) \ { \ for (int i = 0; i < sizeof(args); ++i) { \ /*do something with args[i]*/ \ } \ } 

    Не то, чтобы я мог думать …

    Однако, если ваше приложение для этого обрабатывает переменное количество аргументов одного типа, например:

     foo(0); foo(10, 20, 30); foo(1, 2, 3, 4, 5, 6, 7, 8, 9); 

    и вы не возражаете использовать функцию, чтобы помочь, тогда есть некоторые полезные обманки, которые можно сделать.

    Основная проблема здесь заключается в том, что вы не можете просто передать эти аргументы прямо в функцию varargs, потому что нет возможности для этой функции знать, сколько аргументов нужно читать. И эта проблема может быть решена с помощью некоторой препроцессорной магии:

     #include  #include  #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99-style: anonymous argument referenced by __VA_ARGS__, empty arg not OK */ # define N_ARGS(...) N_ARGS_HELPER1(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) # define N_ARGS_HELPER1(...) N_ARGS_HELPER2(__VA_ARGS__) # define N_ARGS_HELPER2(x1, x2, x3, x4, x5, x6, x7, x8, x9, n, ...) n # define foo(...) foo_helper(N_ARGS(__VA_ARGS__), __VA_ARGS__) #elif defined(__GNUC__) /* GCC-style: named argument, empty arg is OK */ # define N_ARGS(args...) N_ARGS_HELPER1(args, 9, 8, 7, 6, 5, 4, 3, 2, 1) # define N_ARGS_HELPER1(args...) N_ARGS_HELPER2(args) # define N_ARGS_HELPER2(x1, x2, x3, x4, x5, x6, x7, x8, x9, n, x...) n # define foo(args...) foo_helper(N_ARGS(args), args) #else #error variadic macros for your compiler here #endif static inline void foo_helper(unsigned int n_args, ...) { unsigned int i, arg; va_list ap; va_start(ap, n_args); printf("%u argument(s):\n", n_args); for (i = 0; i < n_args; i++) { arg = va_arg(ap, unsigned int); printf(" %u\n", arg); } va_end(ap); } int main(void) { foo(0); foo(10, 20, 30); foo(1, 2, 3, 4, 5, 6, 7, 8, 9); return 0; } 

    Выход:

     $ gcc -W -Wall -std=c99 -pedantic -o va_macro va_macro.c $ ./va_macro 1 argument(s): 0 3 argument(s): 10 20 30 9 argument(s): 1 2 3 4 5 6 7 8 9 $