Использование макроса в качестве аргумента в определении х-макроса - PullRequest
0 голосов
/ 18 мая 2018

Рассмотрим следующий пользовательский стиль x-macro :

#define PRIMES_X(func) \
  func(2) \
  func(3) \
  func(5)

Мы можем использовать это для многократного вызова переданного макроса func с первыми тремя простыми числами.Например:

#define MAKE_FUNC(num) void foo ## num();
PRIMES_X(MAKE_FUNC)

Объявляет функции, возвращающие пустоту foo2(), foo3() и foo5().

Пока все хорошо.Теперь допустим, что я хочу использовать макрос в определении самого x-макроса в качестве аргумента следующим образом:

#define MAX_PRIME 5
#define PRIMES_X(func) \
  func(2) \
  func(3) \
  func(MAX_PRIME)

Он не работает, потому что MAKE_FUNC теперь попытается объявитьvoid fooMAX_PRIME(), поскольку (я полагаю) конкатенация токенов происходит без расширения MAX_PRIME.

Можно ли это исправить, чтобы она объявляла foo5(), как и раньше?

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

Ответ от Yunnosch - это хорошо, но, чтобы немного ускорить безумие X-макроса, вы также можете сделать это с помощью вызова макроса внутри списка, а не макроса-оболочки вне него.Преимущество этого в том, что вы можете передавать «переменные» из списка вызываемому макросу.

Я полагаю, что это может иметь какое-то применение - предположим, например, что вы хотите использовать макрос X для объявления функций различныхтипы?

Пример:

#define MAX_PRIME 5

#define CREATE_FUNC(func, ret_type, param) func(ret_type, param)

#define PRIMES_X(func)                 \
  CREATE_FUNC(func, int,    2)         \
  CREATE_FUNC(func, void,   3)         \
  CREATE_FUNC(func, double, MAX_PRIME) \

#define MAKE_FUNC(ret_type, num) ret_type foo ## num(void);
  PRIMES_X(MAKE_FUNC)
#undef MAKE_FUNC

Отладочный код для проверки того, что функции действительно получили ожидаемые прототипы:

int main(void)
{
  (void)foo2();
  foo3();
  (void)foo5();
}

int foo2 (void){ return 0;}
void foo3 (void){}
double foo5 (void){ return 0.0;}
0 голосов
/ 18 мая 2018

Вы можете вставить другой уровень макроразложения (PRIMES_X2 ниже).

#define MAKE_FUNC(num) void foo ## num();
#define MAX_PRIME 5
#define PRIMES_X(func) PRIMES_X2(func, MAX_PRIME)
#define PRIMES_X2(func, maxPrimePar) \
  func(2) \
  func(3) \
  func(maxPrimePar)

PRIMES_X(MAKE_FUNC)

Вывод с gcc -E:

void foo2(); void foo3(); void foo5();
...