运算符 '!' 的操作数是不允许的[MISRA 2012 规则 10.1,必需]

Unpermitted operand to operator '!' [MISRA 2012 Rule 10.1, required]

正在观察以下代码部分的 Misra 警告。

Unpermitted operand to operator '!' [MISRA 2012 Rule 10.1, required]

不确定可以通过什么修复来消除此警告。

#define C_BYTE unsigned char
C_BYTE SessionStatus;
#define DISCONNECTED   0x10

if((!(SessionStatus & (C_BYTE) DISCONNECTED)))
{
   //Do something
}

我尝试了几次,但没有成功。

1)

if((~(SessionStatus & (C_BYTE) DISCONNECTED)))
{
       //Do something
}

2)

if((!(SessionStatus & (C_BYTE) DISCONNECTED)) != 0u)
{
       //Do something
}

出现警告的原因是 MISRA-C 规则 10.1 要求 ! && || 运算符的操作数为 "essentially boolean"。在你的例子中,它实际上是一个 int,因为

你的第二个例子几乎解决了它,但你必须在 应用 ! 之前转换为本质上的布尔值 。即:

if(!( (SessionStatus & (C_BYTE)DISCONNECTED) != 0u )) 

这没问题,因为 != 运算符的结果基本上被视为布尔值。所以该代码符合 MISRA-C,但有点难以阅读。相反,我会推荐这个:

#define DISCONNECTED   0x10u // u suffix makes this essentially unsigned
...

bool disconnected = (bool) (SessionStatus & DISCONNECTED);
if(!disconnected)

整型常量加上u后缀,本质上是无符号的,与unsigned char类型相同。因此 & 操作在不使用任何转换的情况下是有效的。但是,我们不允许从本质上无符号隐式转换为本质上布尔值,因此将转换添加到 bool.

编辑

由于 SessionStatus & DISCONNECTED 是 "composite expression",MISRA 不允许将结果分配或转换为不同或更广泛的基本类型。理由是他们害怕无能的程序员认为例如 (uint32_t)(u16a + u16b) 中的计算是因为转换而用 uint32_t 进行的,这当然是无稽之谈。 (教育程序员了解基本的 C 语言比提出人为的规则要好,但无论如何......)

我建议完全忽略此规则,但如果您出于某种原因不能这样做,这里有一个替代修复方法:

#define DISCONNECTED   0x10u
...

unsigned char disconnected = SessionStatus & DISCONNECTED;
if(!(bool)disconnected)

当然,这比我的第一个例子更糟糕。