[Linux] 在 C/C++ 裡面使用 ## 和 __VA_ARGS__ 寫巨集指令

[Linux] 在 C/C++ 裡面使用 ## 和 __VA_ARGS__ 寫巨集指令

今天寫了一段 C 的程式,想要建立一個 STL map,

裡面每個不同的 mode 會有其對應的 bool 陣列,所以一開始寫得像這樣:

bool arrayMode0[] = { false };
bool arrayMode1[] = { false, true };
bool arrayMode2[] = { true, false };
bool arrayMode3[] = { true };
mapResult[0] = std::list<bool>(arrayMode0, arrayMode0+sizeof(arrayMode0)/sizeof(arrayMode0[0]));
mapResult[1] = std::list<bool>(arrayMode1, arrayMode1+sizeof(arrayMode1)/sizeof(arrayMode1[0]));
mapResult[2] = std::list<bool>(arrayMode2, arrayMode2+sizeof(arrayMode2)/sizeof(arrayMode2[0]));
mapResult[3] = std::list<bool>(arrayMode3, arrayMode3+sizeof(arrayMode3)/sizeof(arrayMode3[0]));

 

但是程式碼的重覆性太高了….

當然也可以考慮用函式來 refactor,不過另一種方法是利用巨集指令 (macro)~

如下例,我們定義了一個 ADD_MODE 的巨集指令:

#define ADD_MODE(mode, ...) \
    bool arrayMode##mode[] = { __VA_ARGS__ }; \
    mapResult[mode] = std::list<bool>(arrayMode##mode, arrayMode##mode+sizeof(arrayMode##mode)/sizeof(arrayMode##mode[0]));

 

上面用到了 ## 來將 mode 和前面的 arrayMode 組成一個字串,

所以如果 mode 是 0 的時候就會組出 arrayMode0~

 

我們還在 ADD_MODE() 的參數裡用上了 … 這種變動型的參數,

這樣就可以在巨集定義裡面,使用 __VA_ARGS__ 來取得所有剩下的參數 (gcc 限定),

例如呼叫 ADD_MODE(1, a, b, c) 的話,__VA_ARGS__ 就會包含 a, b, c 三個參數~

 

定義好巨集之後,下面的巨集指令就可以定義出最一開始的程式了:

ADD_MODE(0, false);
ADD_MODE(1, false, true);
ADD_MODE(2, true, false);
ADD_MODE(3, true);

 

參考資料:

gcc – Concatenation

gcc – Variadic Macros

(本頁面已被瀏覽過 712 次)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料