2016-08-16 84 views
3

從C語言程序設計,通過KRC嵌套宏和##

#define cat(x, y)  x ## y 

通話cat(var, 123)產量var123。但是,呼叫 cat(cat(1,2),3)未定義:##的存在阻止 外部呼叫的參數被擴展。因此它 產生標記字符串cat ( 1 , 2 )3)3(第一個參數的最後一個標記與第二個標記的第一個標記 的連接)不是合法標記。

如果引入宏定義的第二級,

#define xcat(x, y)  cat(x,y) 

事情的工作更加順利; xcat(xcat(1, 2), 3)確實產生 123,因爲xcat本身的擴展本身不涉及 ##算子。

##的性質是什麼,使兩個例子有所不同?

爲什麼第一個示例中的內部cat(1,2)未展開,而第二個示例中的內部xcat(1,2)是?

謝謝!

回答

1

這是宏##運算符的一個不太爲人所熟知的特性,它禁止進一步擴展其參數(它只是將它們視爲普通字符串)。從GCC預處理器文檔的摘錄:

...與字串,實際參數不是宏展開第一...

也就是說,參數##已擴展。

通過實施使用xcat宏觀你解決該問題的額外的間接(A過程被稱爲參數預掃是跳躍的,實際上評估結果字符串兩次)

+0

感謝。你能解釋爲什麼「通過使用你正在解決問題的xcat宏實現額外的間接尋址」? – Tim

+0

如果「xcat(xcat(1,2),3)確實產生了123」,那麼每個「xcat(a,b)」將首先擴展爲「cat(a,b)」,然後是'a ## b'。我猜外面的'xcat'首先被擴展,接着是內部的'xcat',所以當第一次出現##時,它將阻止任何進一步的擴展,然後爲什麼會說「xcat(xcat ),3)產生123「? – Tim