宏定義代碼段css
#define DEFINE_LDST_DMA(_lname, _sname, _bits, _end) \ static inline uint##_bits##_t ld##_lname##_##_end##_dma(AddressSpace *as, \ dma_addr_t addr) \ { \ uint##_bits##_t val; \ dma_memory_read(as, addr, &val, (_bits) / 8); \ return _end##_bits##_to_cpu(val); \ } \ static inline void st##_sname##_##_end##_dma(AddressSpace *as, \ dma_addr_t addr, \ uint##_bits##_t val) \ { \ val = cpu_to_##_end##_bits(val); \ dma_memory_write(as, addr, &val, (_bits) / 8); \ }
調用宏定義不一樣的函數,如下代碼實際定義了12個返回類型、函數名、函數內部變量類型不一樣的函數函數
DEFINE_LDST_DMA(uw, w, 16, le); DEFINE_LDST_DMA(l, l, 32, le); DEFINE_LDST_DMA(q, q, 64, le); DEFINE_LDST_DMA(uw, w, 16, be); DEFINE_LDST_DMA(l, l, 32, be); DEFINE_LDST_DMA(q, q, 64, be);
其做用是:將宏定義中的傳入參數名轉換成用一對雙引號括起來參數名字符串。其只能用於有傳入參數的宏定義中,且必須置於宏定義體中的參數名前
例如宏定義代碼ui
#define M(x) printf("result = %s",#x)
執行該宏定義.net
int a=1; M(A);
實際結果爲code
result = A
例如blog
#define A1(name, type) type name_##type##_type 或 #define A2(name, type) type name##_##type##_type A1(a1, int); /* 等價於: int name_int_type; */ A2(a1, int); /* 等價於: int a1_int_type; */
解釋:字符串
1) 在第一個宏定義中,"name"和第一個""之間,以及第2個""和第二個"type"之間沒有被分隔,因此預處理器會把name_##type##_type
解釋成3段:get
「name_」、「type」、以及「_type」,這中間只有「type」是在宏前面出現過scss
的,因此它能夠被宏替換。it
2) 而在第二個宏定義中,「name」和第一個「_」之間也被分隔了,因此
預處理器會把name##_##type##_type
解釋成4段:「name」、「_」、「type」
以及「_type」,這其間,就有兩個能夠被宏替換了。
3) A1和A2的定義也能夠以下:
#define A1(name, type) type name_ ##type ##_type
<##前面隨意加上一些空格>
#define A2(name, type) type name ##_ ##type ##_type
結果是## 會把前面的空格去掉完成強鏈接,獲得和上面結果相同的宏定義
若是##後的參數自己也是一個宏的話,##會阻止這個宏的展開,也就是隻替換一次。
#define STRCPY(a, b) strcpy(a ## _p, #b) int main() { char var1_p[20]; char var2_p[30]; /* 注意這裏 */ STRCPY(STRCPY(var1,var2),var2); /* 這裏是否會展開爲: strcpy(strcpy(var1_p,"var2")_p,"var2「)? * 答案是否認的: * 展開結果將是: strcpy(STRCPY(var1,var2)_p,"var2") * ## 阻止了參數的宏展開! * 若是宏定義裏沒有用到 # 和 ##, 宏將會徹底展開 */ }
詳見參考:
http://blog.csdn.net/jiangjingui2011/article/details/6706967