2012-03-01 139 views
2

我想跟踪宏扩展 - 宏扩展了多少次,扩展发生时参数是多少。跟踪宏扩展

例如,

我有一个宏可能是这样的:

#define mymacro(x) int x 

,并在我的代码,我有这样的事情:

mymacro(a); 
mymacro(b); 

在预处理结束扩展(是的,有没有办法让一个特定的宏成为最后扩展?),我想知道多少次mymacro已被使用,哪些参数通过。在这种情况下,它会是2倍,参数是a和b。

我正在研究boost-preprocessor lib。他们有BOOST_PP_ARRAY,但我不知道如何使它成为“静态”,以便我可以在以后使用它。

我在BOOST_PP_COUNTER中发现了一些东西。它看起来像BOOST_PP_COUNTER是可以在预处理器短语中保持其状态的东西。但我仍不清楚如何做我想做的事。

+0

如果您的编译器支持,可以通过向输出编译器消息的宏添加一行来完成此操作。 – 2012-03-01 02:07:18

+0

你能更具体吗?我正在使用Clang – 2012-03-01 02:32:50

+0

这个问题我并不清楚,但是你正在通过检查发生的事情并且希望得到结果(即它被调用的内容等)在预处理时可用,以便你可以做一些事情有它,对吧? – 2012-03-01 07:55:41

回答

0

这样的事情呢?

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

嗯......在这种情况下,需要调用M(x)和M(y)运行时,才能工作。我的马科斯是回调,所以不会被调用。无论如何在编译时做到这一点? – 2012-03-01 17:38:46

0

我不是很确定你的最终目标是什么,但你可以跟踪扫描使用有源参数的数量(不扩展数)。每次被预处理器扫描时,激活的参数都会扩展。例如,

#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的每一次调用经受不同数量的扫描,这会导致每个时间的结果是不同的。

宏不能影响全局状态。实现某种状态的唯一方法是使用递归。请记住,宏不会递归地扩展,所以预处理器会跟踪这个状态。它是唯一可以受宏观影响的“全局”状态。但是,可能难以控制。必须强制宏以某个递归级别进行扩展,每个级别都有一个宏,并且需要某种形式的二进制搜索来有效地读取“状态”。