【问题标题】:MISRA-2012 Rule 20.12 violation: misra_c_2012_rule_20_12_violation: macro parameter "val" is used in both expanded and raw formsMISRA-2012 违反规则 20.12:misra_c_2012_rule_20_12_violation:宏参数“val”用于扩展和原始形式
【发布时间】:2019-05-23 13:08:54
【问题描述】:

我一直面临这种 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

【问题讨论】:

  • 由于您标记了此安全关键代码,因此使用此代码实际上是犯罪行为...

标签: c embedded qnx misra safety-critical


【解决方案1】:

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

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

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

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

【讨论】:

  • 谢谢 是的.. #define A (1UL &lt; 10) 是错误的.. 我已经编辑了问题。
  • 实际上,为“疯狂片段”使用宏,例如“(1UL
  • 在我的真实代码中……我没有犯这个错误……只是在这里提出问题时……我打错了; :)
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多