閱讀某專案時,遇到了以下兩個神奇的宏用法
IFDEF(CONFIG_DEVICE, init_device());
MUXDEF(CONFIG_TRACE, "ON", "OFF")
顧名思義,第一個的意思就是如果定義了CONFIG_DEVICE宏才執行后面的函式呼叫,第二個的含義則是如果定義了CONFIG_TRACE宏則為"ON",否則為"OFF",
大家可以思考思考,這樣的宏你們會怎么實作呢?
Hint:并不簡單哦,會用到不少宏定義的技巧,(如果你有簡單的方法請一定留言告訴我!)
點擊查看解答
// macro concatenation
#define concat_temp(x, y) x ## y
#define concat(x, y) concat_temp(x, y)
// macro testing
// See https://stackoverflow.com/questions/26099745/test-if-preprocessor-symbol-is-defined-inside-macro
#define CHOOSE2nd(a, b, ...) b
#define MUX_WITH_COMMA(contain_comma, a, b) CHOOSE2nd(contain_comma a, b)
#define MUX_MACRO_PROPERTY(p, macro, a, b) MUX_WITH_COMMA(concat(p, macro), a, b)
// define placeholders for some property
#define __P_DEF_0 X,
#define __P_DEF_1 X,
// define some selection functions based on the properties of BOOLEAN macro
#define MUXDEF(macro, X, Y) MUX_MACRO_PROPERTY(__P_DEF_, macro, X, Y)
// simplification for conditional compilation
#define __IGNORE(...)
#define __KEEP(...) __VA_ARGS__
// keep the code if a boolean macro is defined
#define IFDEF(macro, ...) MUXDEF(macro, __KEEP, __IGNORE)(__VA_ARGS__)
解釋每一個宏很枯燥,不如讓做一個人形前處理器,直接針對第一個宏用法對其進行展開(第二個宏的用法包含在第一個之中)
// For CONFIG_DEVICE not defined
IFDEF(CONFIG_DEVICE, init_device());
MUXDEF(CONFIG_DEVICE, __KEEP, __INGORE)(init_device());
MUX_MACRO_PROPERTY(__P_DEF_, CONFIG_DEVICE, __KEEP, __INGORE)(init_device());
MUX_WITH_COMMA(concat(__P_DEF_, CONFIG_DEVICE), __KEEP, __INGORE)(init_device());
MUX_WITH_COMMA(__P_DEF_CONFIG_DEVICE, __KEEP, __INGORE)(init_device());
CHOOSE2nd(__P_DEF_CONFIG_DEVICE __KEEP, __INGORE)(init_device());
注意以上展開程序保留了CONFIG_DEVICE,如果其定義為1或0,則繼續展開可以得到
CHOOSE2nd(X, __KEEP, __INGORE)(init_device());
__KEEP(init_device());
init_device();
如果其沒有定義則該陳述句直接變成了一條空陳述句,
怎么樣是不是很神奇呢?
原文鏈接:https://www.cnblogs.com/zhangyi1357/p/16192431.html
轉載請注明出處!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/464000.html
標籤:C++
