2013-03-14 29 views
2

名稱下面迭代器宏給我(不能改變)捕獲使用C宏

#define ITERATE(MACRO) \ 
    MACRO(v1) \ 
    MACRO(v2) \ 
    MACRO(v3) \ 
    MACRO(v4) 

這背後的想法是,我現在可以定義自己的一個參數的宏,並將其傳遞到迭代器擴大爲v1v2,v3,v4。例如:

#define MYSTUFF(X) doSth(X); 
ITERATE(MYSTUFF) 

將擴大到

doSth(v1); doSth(v2); doSth(v3); doSth(v4); 

我現在的問題是,我想這想傳遞一個額外的參數爲MYSTUFF超出一個提供的另一個宏內調用ITERATEITERATE

爲了實現這個目標,我希望我可以用下面的結構捕捉額外的參數名稱:

#define PARTIAL(T) FULL(UUU,T) 
#define FULL(U,V) doSth(U,V) 
#define START(UUU) ITERATE(PARTIAL) 
START(bla) 

我希望,當ITERATE(PARTIAL)被擴展爲:

FULL(UUU,v1) FULL(UUU,v2) FULL(UUU,v3) FULL(UUU,v4) 

我居然還會捕獲START的參數UUU,它將被替換爲bla。不幸的是,情況並非如此(至少在gcc中)。

  • 你知道這樣的名稱捕獲是否可以實現不同嗎?
  • 或者您可能有不同的想法如何解決將額外參數傳入MACRO的問題?
  • 我可能會被允許更改ITERATOR定義本身,但前提是它不破壞任何現有代碼已經使用它。
+1

如果您不允許更改宏,您是否至少允許用非宏代碼替換它? – stefan 2013-03-14 16:43:03

+0

當然,我可以簡單*不*使用'ITERATE',或者自己創建一個可以接受更多參數的函數 - 如果這是您要求的。但我寧願避免這種情況。 – CygnusX1 2013-03-14 16:48:24

+4

我建議徹底擺脫宏的使用,而不是寫另一個 – stefan 2013-03-14 16:50:55

回答

2

你不能這樣做。宏你的START()基本上只有一個參數,然後丟棄。

你可以做的是定義UUU你需要它,例如。

#define PARTIAL(T) FULL(UUU,T) 
#define FULL(U,V) doSth(U,V) 
#define START() ITERATE(PARTIAL) 

// ... 

#define UUU blah 

START() 

#undef UUU 
2

你的問題,簡化的,看起來是這樣的:

#define FOO UUU 
#define START(UUU) FOO 
START(5) 

這裏發生了什麼:

  • 宏觀START在線路遇到START(5)
    • START是一個函數樣宏,所以它變得擴大與論點UUU = 5):
      • 階段1(自變量擴展):宏參數是宏擴展
        沒有任何反應,5不是宏。
        身體:FOO
      • 階段2(argument prescan):宏參數代入宏體。
        沒有任何反應,UUU不在體內。
        身體:FOO
      • 階段3(膨脹):身體宏擴展再次
        FOO被擴展成UUU,這不是一個宏。
        身體:UUU

我想不出任何聰明的方式來擴大FOO身體內部的說法預掃描發生之前。我認爲不可能直接做你想做的事。

跟@Hasturkun的解決方法,並使UUU宏,而不是一個參數。

+0

感謝您對宏如何工作的明確解釋。 – CygnusX1 2013-03-14 17:38:49