利用宏定義中的##實現函數模板的做用

利用宏定義的##完成函數模板的定義與調用

宏定義代碼段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

相關文章
相關標籤/搜索