2012-07-01 52 views
1

是可以定義一個宏BREF(...):宏分配給函數調用

struct bits 
{ 
    int b0:1; 
    int b1:1; 
    int b2:1; 
    int b3:1; 
    int b4:1; 
    int b5:1; 
    int b6:1; 
    int b7:1; 
} 

#define BREF(var,bit) ???? 
#define BAR 4 
#define ALIAS BREF(foo,BAR) 

unsigned char foo; 

,使得這樣的說法:

ALIAS = 1; 

擴展到這一點:

((struct bits *)&foo)->b4 = 1; 

和這個:

int k = ALIAS; 

這樣:

int k = ((struct bits *)&foo)->b4; 

到目前爲止,這是我實現BREF(...)的:

#define BREF(var,bit) (((struct bits *) &(var))->b##bit) 

但是,如果bit是文字數字這僅適用。我希望能夠傳遞一個擴展爲數字的宏變量。如何在將C預處理器連接到b之前將其擴展爲bit

回答

2

您可以使用擴展的一個額外的步驟,就像這樣:和

#define BITATTR(num) b##num 
#define BREF(var,bit) (((struct bits *) &(var))->BITATTR(bit)) 
+0

謝謝,這個作品完美!我已經完成了兩個級別的擴展,但從來沒有串聯。 – gvl

3

訣竅是,C預處理器將擴展宏參數僅當沒有與所述字符串化(#)或標記粘貼(##)運營商使用它們。因此,爲了使其與擴展到數字文字宏的工作,像這樣添加宏額外的一層:

#define CONCAT(x, y) x ## y 
#define BREF(var,bit) (((struct bits *) &(var))-> CONCAT(b, bit)) 

根據這個定義,bit不再令牌粘貼操作的直接的說法,所以如果它是一個宏,它會在令牌粘貼之前擴展。

+0

很好的嘗試,但這種方法的問題是,預處理堅持''B'一起EXPAND'之前,甚至困擾擴大'bit'。 – gvl

+0

哎呀抱歉,您是對的,並且正是我說的原因!我錯過了測試,但現在它已經修復了。 –