Reputation: 1
I was studying the Linux wireless subsystem code and noticed this code (in ieee80211_rx_handlers):
It first defines the macro:
#define CALL_RXH(rxh) \
do { \
res = rxh(rx); \
if (res != RX_CONTINUE) \
goto rxh_next; \
} while (0);
Then the macro is used to call a series of functions:
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)
My question is, why not just call the functions directly like:
ieee80211_rx_h_check_more_data(rx);
ieee80211_rx_h_uapsd_and_pspoll(rx);
...
Is it just for the sake of outlining the code for easy reading?
Upvotes: 0
Views: 157
Reputation: 472
The do {} while(0) Macro could be easily used in condition block.
#define FUNC1() doing A; dong B;
#define FUNC2() do { doing A; doing B; } while(0)
We could use FUNC2() in if condition code block like this:
if (true)
FUNC2();
But FUNC1() could only be used like this:
if (true) {
FUNC1()
}
Upvotes: 0
Reputation: 137820
Each use of the macro expands into the if
check and goto
, not just a single function call.
The if
tests differ only by which function is called to produce the condition. Because the code would otherwise be repetitive, they used a macro to generate the boilerplate.
They could perhaps have interspersed calls res = xyz( rx );
with a macro expanding to the if … goto
part, and then the macro would not take any parameter. How much gets encapsulated into the macro is a matter of code factoring style.
Upvotes: 1