Acompanhe a expansão macro
-
14-11-2019 - |
Pergunta
Quero acompanhar a expansão da macro - quantas vezes a macro foi expandida e quais são os argumentos quando a expansão ocorreu.
Por exemplo,
Eu tenho uma macro que pode ficar assim:
#define mymacro(x) int x
e no meu código tenho algo assim:
mymacro(a);
mymacro(b);
no final da expansão do pré-processador (ah sim, existe uma maneira de fazer com que uma macro específica se torne a última a expandir?), gostaria de saber quantas vezes minha macro foi usada e quais são os argumentos passados.Nesse caso, seria 2 vezes e args seria a e b.
Eu estava investigando a biblioteca do pré-processador boost.Eles têm BOOST_PP_ARRAY, mas não sei como torná-lo "estático", para poder usá-lo mais tarde.
Encontrei algo no BOOST_PP_COUNTER.Parece que BOOST_PP_COUNTER é algo que pode manter seu estado na frase do pré-processador.Mas ainda não estou claro como fazer o que queria.
Solução
Que tal algo como isso?
#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";
}
}
Outras dicas
Não tenho certeza de qual é o seu objetivo final, mas você pode rastrear o número de varreduras (não o número de expansões) usando um argumento ativo.Um argumento ativo se expande cada vez que é varrido pelo pré-processador.Por exemplo,
#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)
Cada invocação de A é submetida a um número diferente de varreduras, o que faz com que os resultados sejam diferentes a cada vez.
As macros não podem afetar o estado global.A única outra maneira de alcançar algum tipo de estado é usar recursão.Lembre-se de que as macros não se expandem recursivamente, portanto o pré-processador mantém registros desse estado.É o único estado “global” que pode ser afetado por macros.No entanto, pode ser difícil de controlar.As macros precisam ser forçadas a se expandir em um determinado nível de recursão com uma macro para cada nível, e alguma forma de pesquisa binária é necessária para ler o "estado" com eficiência.