Следите за расширением макроса - PullRequest
2 голосов
/ 01 марта 2012

Я хочу отслеживать раскрытие макроса - сколько раз макрос был раскрыт и каковы аргументы, когда произошло расширение.

Например,

У меня макрос может выглядеть так:

#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 ]

0 голосов
/ 09 марта 2012

Я не совсем уверен, какова ваша конечная цель, но вы можете отслеживать количество сканирований (не количество расширений), используя активный аргумент.Активный аргумент расширяется каждый раз, когда он сканируется препроцессором.Например,

#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 подвергается разному количеству сканирований, что каждый раз приводит к разным результатам.

Макросы не могут влиять на глобальное состояние.Единственный способ достичь состояния - использовать рекурсию.Помните, что макросы не расширяются рекурсивно, поэтому препроцессор отслеживает это состояние.Это единственное «глобальное» состояние, на которое могут влиять макросы.Тем не менее, это может быть трудно контролировать.Макросы должны быть развернуты на определенном уровне рекурсии с макросом для каждого уровня, и для эффективного чтения «состояния» требуется некоторая форма двоичного поиска.

0 голосов
/ 01 марта 2012

Как насчет этого?

#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";
    }
}
...