Следите за расширением макроса
Я хочу отслеживать расширение макроса - сколько раз макрос был раскрыт и каковы аргументы, когда произошло расширение.
Например,
У меня макрос может выглядеть так:
#define mymacro(x) int x
и в моем коде у меня есть что-то вроде этого:
mymacro(a);
mymacro(b);
в конце расширения препроцессора (о, да, есть ли способ сделать конкретный макрос, который станет последним расширением?), я хотел бы знать, сколько раз использовался mymacro и какие аргументы были переданы. В этом случае это будет 2 раза, а аргументы будут a и b.
Я исследовал lib-препроцессора lib. У них есть BOOST_PP_ARRAY, но я не знаю, как сделать это "статичным", чтобы я мог использовать его позже.
Я нашел что-то в BOOST_PP_COUNTER. Похоже, что BOOST_PP_COUNTER - это то, что может поддерживать свое состояние в фразе препроцессора. Но мне все еще неясно, как делать то, что я хотел.
2 ответа
Как насчет этого?
#include <iostream>
int m_counter = 0;
const char *m_arguments[32] = { 0 };
#define COUNT_M(a) m_arguments[m_counter++] = #a;
#define M(a) COUNT_M(a) int a
int main()
{
M(x);
M(y);
for (int i = 0; i < m_counter; i++)
{
std::cout << "m_arguments[" << i << "] = \"" << m_arguments[i] << "\"\n";
}
}
Я не совсем уверен, какова ваша конечная цель, но вы можете отслеживать количество сканирований (не количество расширений), используя активный аргумент. Активный аргумент расширяется каждый раз, когда он сканируется препроцессором. Например,
#define EMPTY()
#define A(n) \
A_INDIRECT EMPTY()()(BOOST_PP_INC(n))
#define A_INDIRECT() A
#define X(arg) arg
#define Y(arg) X(arg)
#define Z(arg) Y(arg)
A(0) // A_INDIRECT()(1)
X( A(0) ) // A_INDIRECT()(2)
Y( A(0) ) // A_INDIRECT()(3)
Z( A(0) ) // A_INDIRECT()(4)
Каждый вызов A подвергается разному количеству сканирований, что каждый раз приводит к разным результатам.
Макросы не могут влиять на глобальное состояние. Единственный способ достичь состояния - использовать рекурсию. Помните, что макросы не расширяются рекурсивно, поэтому препроцессор отслеживает это состояние. Это единственное "глобальное" состояние, на которое могут влиять макросы. Тем не менее, это может быть трудно контролировать. Макросы должны быть развернуты на определенном уровне рекурсии с помощью макроса для каждого уровня, и для эффективного считывания "состояния" требуется некоторая форма двоичного поиска.