2012-03-01 176 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的每一次調用經受不同數量的掃描,這會導致每個時間的結果是不同的。

宏不能影響全局狀態。實現某種狀態的唯一方法是使用遞歸。請記住,宏不會遞歸地擴展,所以預處理器會跟蹤這個狀態。它是唯一可以受宏觀影響的「全局」狀態。但是,可能難以控制。必須強制宏以某個遞歸級別進行擴展,每個級別都有一個宏,並且需要某種形式的二進制搜索來有效地讀取「狀態」。