运算符“>>”和“&”的不允许操作数 (MISRA C)

Unpermitted operand to operator '>>' and '&' (MISRA C)

使用 Misra 检查一些代码时,它生成了以下消息

Unpermitted operand to operator '>>' [MISRA 2012 Rule 10.1 required]
Unpermitted operand to operator '&' [MISRA 2012 Rule 10.1 required]

我无法理解这个问题,规则 10.1 的描述非常笼统,没有太大帮助。相关代码如下。

float  variable2;
variable2= 814.00f;
Data[0] = (((Int16) variable2) >> 8) & ((Int16)0xFF);
Data[1] =  ((Int16) variable2) & ((Int16)0xFF);

在此代码中使用运算符有什么问题?

永远不要在按位算术中使用有符号整数。有很多与之相关的定义不明确的行为。左移负值会产生未定义的行为。右移负值会产生实现定义的行为(算术或逻辑移位)。

因此 MISRA-C 要求所有这些变量都应该是他们所谓的 essenially unsigned 类型。

此外,在 32 位系统上使用 16 位类型而不考虑符号是不安全的,因为它们将被隐式提升为 32 位符号 int。我假设您使用的是 32 位系统,否则使用浮点数可能一开始就毫无意义。

在你的情况下,你不能直接从 float 转到 unsigned,因为你会丢失符号位。这意味着你必须先一步到签名类型。

float    f32 = 814.00f;
int32_t  s32 = (int32_t)f32;
uint32_t u32 = (uint32_t)s32;

Data[0] = ((u32 >> 8) & 0xFFu);
Data[1] = (u32 & 0xFFu);

这应该是 MISRA-C 兼容的,尽管它也取决于 Data 的类型。

  • u 整数常量的后缀就足够了,你不需要转换它们。
  • 使用 stdint.h 类型而不是一些自制类型。
  • 建议 MISRA-C:2012 12.1 需要在 & 的操作数周围加上额外的括号。您的代码不符合此规则,上面的代码是。