我一直面临着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
发布于 2019-05-23 22:29:54
MISRA-C认为在相同的宏中使用相同的预处理器常量两次是愚蠢的想法,在这种情况下,您让它在一种情况下扩展,但在另一种情况下不扩展。
在你的宏中,val##_MASK
不会被展开,所以你会得到INIT_A_MASK
。但后来在同一个宏中,val
也被扩展并替换为((A) | (1UL << 15))
。
唯一可以接受的解决方案是从头开始重写所有这些疯狂的代码,并摆脱所有秘密宏语言的使用。
例如,#define A (1UL < 10)
到底是什么意思?我假设<<
是故意的。如果不是因为秘密的宏语言,像这样的bug很容易找到。但是,您在应用程序中注入了一个很难找到的休眠bug。
发布于 2019-05-24 03:39:58
不确定这是否在任何情况下都可以工作,当您编写"if (!IS_STATE_IFSET ( INIT_A,INIT_A))“时,状态将立即扩展到其宏定义中,并且名称将不会首先传递到IS_STATE_IFSET的定义中。我猜这是一种情况,你的MISRA校验器的行为与真正的C预处理器不同。
https://stackoverflow.com/questions/56275993
复制相似问题