我正在研究Linux无线子系统代码并注意到这段代码(在ieee80211_rx_handlers中):
首先定义宏:
#define CALL_RXH(rxh) \
do { \
res = rxh(rx); \
if (res != RX_CONTINUE) \
goto rxh_next; \
} while (0);
然后宏用于调用一系列函数:
CALL_RXH(ieee80211_rx_h_check_more_data)
CALL_RXH(ieee80211_rx_h_uapsd_and_pspoll)
CALL_RXH(ieee80211_rx_h_sta_process)
CALL_RXH(ieee80211_rx_h_decrypt)
CALL_RXH(ieee80211_rx_h_defragment)
CALL_RXH(ieee80211_rx_h_michael_mic_verify)
我的问题是,为什么不直接调用函数,如:
ieee80211_rx_h_check_more_data(rx);
ieee80211_rx_h_uapsd_and_pspoll(rx);
...
是否只是为了便于阅读而概述代码?
答案 0 :(得分:1)
每次使用宏都会扩展到if
检查和goto
,而不仅仅是单个函数调用。
if
测试的不同之处仅在于调用哪个函数来生成条件。因为代码可能是重复的,所以他们使用宏来生成样板。
他们或许可以散布调用res = xyz( rx );
并将宏扩展到if … goto
部分,然后宏不会采用任何参数。封装到宏中的多少是代码分解风格的问题。
答案 1 :(得分:0)
do {} while(0)宏可以在条件块中轻松使用。
#define FUNC1() doing A; dong B;
#define FUNC2() do { doing A; doing B; } while(0)
如果条件代码阻塞,我们可以使用FUNC2():
if (true)
FUNC2();
但是FUNC1()只能这样使用:
if (true) {
FUNC1()
}