[英]MISRA-2012 Rule 20.12 violation: misra_c_2012_rule_20_12_violation: macro parameter “val” is used in both expanded and raw forms
我一直在面對這種MISRA違規行為:
#define A (1UL << 10)
#define INIT_A ((A) | (1UL << 15))
#define INIT_A_MASK (0xFFFFUL << 15)
#define IS_STATE_IFSET(state, val) ((((state) & (val##_MASK)) == (val)) ? true : false) //issue is here ?
uint64_t state = 1234UL;
if (!IS_STATE_IFSET(state, INIT_A)) {
printf("Hoo-Haa\n");
}
Misra-2012報告違反規則20.12 misra_c_2012_rule_20_12_violation: macro parameter "val" is used in both expanded and raw forms
MISRA-C認為在同一個宏中兩次使用相同的預處理器常量是一個愚蠢的主意,在這種情況下,您可以在一種情況下擴展它,而在另一種情況下不擴展。
在您的宏val##_MASK
中將不會展開,因此您將獲得INIT_A_MASK
。 但是稍后,在同一宏中, val
也被擴展並替換為((A) | (1UL << 15))
。
唯一可接受的解決方案是從頭開始重寫所有這些瘋狂的代碼,並擺脫對秘密宏語言的所有使用。
例如, #define A (1UL < 10)
的含義是什么? 我認為<<
是故意的。 如果不是秘密的宏語言,則很容易發現此類錯誤。 但是,相反,您在應用程序中注入了一個難以發現的休眠錯誤。
不確定是否在任何情況下都行得通,當您輸入“ if(!IS_STATE_IFSET(state,INIT_A))”時,INIT_A將立即擴展為其宏定義,並且該名稱不會傳遞給IS_STATE_IFSET的定義首先。 我猜這是您的MISRA檢查器的行為與真實C預處理程序不同的情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.