Question

I want to keep track of macro expansion - how many times the macro has been expanded and what are the args when expansion happened.

For example,

I have a macro might look like this:

#define mymacro(x) int x

and in my code I have something like this:

mymacro(a);
mymacro(b);

in the end of the preprocessor expansion (oh yeah, is there a way to make a specific macro to become the last to expand?), I would like to know how many times mymacro has been used and what are the args passed. In this case, it would be 2 times, and args would be a and b.

I was investigating boost-preprocessor lib. They have BOOST_PP_ARRAY, but I don't know how to make it "static", so that I can use it in later.

I found something in the BOOST_PP_COUNTER. It looks like the BOOST_PP_COUNTER is something that can maintain its state in preprocessor phrase. But I am still unclear how to do what I wanted.

Was it helpful?

Solution

How about something like this?

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

OTHER TIPS

I'm not quite sure what your ultimate goal is, but you can track the number of scans(not the number of expansions) using an active argument. An active argument expands each time that it is scanned by the preprocessor. For example,

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

Each invocation of A is subjected to a different number of scans, which causes the results to be different each time.

Macros can't effect the global state. The only other way to achieve some sort of state is to use recursion. Remember, macros don't expand recursively, so the preprocessor keeps tracks of this state. Its the only "global" state that can be affected by macros. However, it can be difficult to control. Macros have to be forced to expand at a certain recursion level with a macro for each level, and some form of binary searching is required to read the "state" efficiently.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top