宏的幾種特殊用法

1. 屏蔽“未使用參數”警告

在OceanBase中ob_define.h中就使用了這種宏,將傳入的數據強制轉化爲void型。

   #ifndef UNUSED
    #define UNUSED(v) ((void)(v))
    #endif


這種宏主要是爲了屏蔽“未使用參數”的警告,如下面這個函數用兩個參數,但是一個都不用的話,某些編譯器就會報出警告:認爲p和mod_id都沒有使用。所有我們使用UNUSE宏,這樣兩個參數都被使用了,但是實際上沒有做任何有效的動作,以此來屏蔽“未使用參數”警告。

 virtual void mod_free(void* p, const int32_t mod_id = 0)
 { 
    UNUSED(p); 
    UNUSED(mod_id); 
 }


2. 指定字節對齊

在缺省情況下,編譯器爲每一個變量或是數據單元按其自然對界條件分配空間。一般地,可以通過下面的方法來改變缺省的對界條件:
1) 使用僞指令#pragma pack (n),編譯器將按照n個字節對齊。
2) 使用僞指令#pragma pack (),取消自定義字節對齊方式。
另外,還有如下的一種方式:
3) __attribute__((aligned (n))),讓所作用的結構成員對齊在n字節自然邊界上。如果結構中有成員的長度大於n,則按照最大成員的長度來對齊。
4) __attribute__ ((packed)),取消結構在編譯過程中的優化對齊,按照實際佔用字節數進行對齊。
以上的n = 1, 2, 4, 8, 16... 第一種方式較爲常見。

#define CACHE_ALIGNED __attribute__((aligned(CACHE_ALIGN_SIZE)))


3. 可變參數宏

我們指定,有些函數的參數是可變的,例如printf函數,指定第一個爲格式化字符串以後,後面可以跟個數不定的參數,同樣,宏也可以指定多個參數。有兩種方法可以做到。
一是使用args...##args,二是使用...__VA_ARGS__。下面是兩種方式定義的兩個宏,這兩個宏都能在printf字符串前,先輸出一個字符串,達到相同的效果。

#define P_Debug(format,args...) \
{\
    printf("[DeBug]");\
    printf(format,##args);\
}while(false)
#define P_Release(format,...) \do{\
    printf("[Release]");\
    printf(format,__VA_ARGS__);\
}while(false)


使用的時候爲:

P_Debug("%s:%d\n","good",100);
P_Release("%s:%d\n","good",100);


4. ###,#@的區別

假設定義3個宏,

#define A(x) T_##x
#define B(x) #@x
#define C(x) #x


則下面展開後爲
A(1)------>T_1
B(1)------>'1'
C(1)------>"1"


歡迎光臨我的網站----蝴蝶忽然的博客園----人既無名的專欄
如果閱讀本文過程中有任何問題,請聯繫作者,轉載請註明出處!


發佈了35 篇原創文章 · 獲贊 47 · 訪問量 37萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章