我正在根据 MISRA 规则编写代码。我收到以下表达式的 MISRA 错误
check_Val = ( ~( 0x000Fu << Src_Data ) ); //其中 Src_Data 是 uint8,check_Val 是 uint32。
我分析了错误
违反 MISRA 2004 要求的规则 10.1,复杂整数表达式的隐式转换
因为 check_Val 是uint32
,所以 Lf 应该适合它。那么为什么它给出一个错误。
规则 10.1 关注整数的隐式提升,通过使用 MISRA:2004 的“基础类型”概念,即表达式的预期类型。这是一个奇怪的概念,导致大量多余的演员表,这已在 MISRA:2012 中得到修复。
表达式的基础类型是整数文字的类型0x000Fu
。对于整数文字,它声明底层类型是能够表示对象的最小可能类型(参见 p40-41)。所以底层类型0x000Fu
will 是uint8_t
,因为它可以容纳在一个字节中并且它是无符号类型。
尽管就 C 语言和编译器而言,整数文字实际上是类型unsigned int
,并且不会发生任何提升。MISRA:2004 不在乎。
这意味着您必须在操作uint32_t
之前将操作数转换为(绕过规则 10.1)或uint8_t
在操作之后将其转换为(以满足 10.1 和 10.5 关于班次的要求)。我建议您将其转换为 uint32_t 以解决此问题。
因此,固定代码应该是
check_Val = ~( (uint32_t)0x000Fu << Src_Data );
此外,由于移位运算符的两个操作数都是整数提升的,因此右手运算符也被隐式提升int
为。这种促销永远不会造成伤害,我不确定它是否违反了 MISRA,但我想它也可能会引起警告。在这种情况下,您还必须转换正确的操作数:
check_Val = ~( (uint32_t)0x000Fu << (uint32_t)Src_Data );
如果可能,我会建议使用 MISRA:2012,其中这些规则已得到澄清,并且“基础类型”概念已被一个不会导致如此多无意义的强制转换的概念所取代。