0

我一直面临着这种 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.12misra_c_2012_rule_20_12_violation: macro parameter "val" is used in both expanded and raw forms

4

2 回答 2

2

MISRA-C 认为在同一个宏中使用相同的预处理器常量两次是愚蠢的想法,在这种情况下你让它在一种情况下扩展但在另一种情况下不扩展。

在你的宏val##_MASK中不会被扩展,所以你得到INIT_A_MASK. 但后来在同一个宏val中也被扩展并替换为((A) | (1UL << 15)).

唯一可接受的解决方案是从头开始重写所有这些疯狂的代码,并摆脱所有秘密宏语言的使用。

例如,到底是什么意思#define A (1UL < 10)?我想<<是故意的。如果不是因为秘密宏语言,这样的错误很容易找到。但相反,您在应用程序中注入了一个难以发现的休眠错误。

于 2019-05-23T14:29:54.130 回答
-1

不确定这是否可以在任何情况下工作,当您编写“if (!IS_STATE_IFSET(state, INIT_A))”时,INIT_A 将立即扩展为其宏定义,并且名称不会传递给 IS_STATE_IFSET 的定义首先。我想这是您的 MISRA 检查器的行为与真正的 C 预处理器不同的情况。

于 2019-05-23T19:39:57.783 回答