MISRA 不赞成复合作业吗?
不是这样的。复合赋值的规则类似于简单赋值的规则。MISRA 在一般情况下谈到赋值运算符,包括所有这些运算符。
然而,MISRA 不赞成隐式类型提升,请参阅隐式类型提升规则。除非您了解隐含促销,否则您无法理解这些 MISRA 警告。
有什么快速解决方法,而不是忽略警告?
如果不了解警告,您将无法真正解决此问题。唯一的快速解决方法是只uint32_t
在任何地方使用,从不使用有符号或小整数类型,但这并不总是可行的。如果所有变量都是uint32_t
.
一般来说,最新的 MISRA 只允许同一基本类型类别的类型之间进行各种转换。无符号整数是这样的一类,有符号整数是另一类,依此类推。
在不知道 and 的类型的情况下,很难判断您的代码究竟是如何违反 MISRAB
的sizeof(int)
。这与复合赋值本身没有任何关系,除了复合赋值运算符在涉及隐式提升时使用起来有点麻烦。
MISRA 不赞成将表达式的值(在隐式提升之后)分配给同一类别的更窄的基本类型或不同的类别。用简单的英语来说,例如,您不应该将uint32_t
操作的结果分配给uint16_t
变量,或者将有符号的结果分配给无符号的变量。这通常通过在适当的位置进行铸造来解决。
关于您的具体示例,假设 B 是uint16_t
并且 CPU 是 32 位,那么您会遇到隐式类型提升的问题。
由于A |= B
等价于,因此在 32 位 CPU 的情况下,A | B
通常的算术转换会将操作数提升为。int
所以它是有符号的 32 位类型。
假设您有A << 31u
- 那么这实际上会调用一个未定义的行为错误,该规则试图防止该错误。
MISRA-C 合规性的充分修复:
A = (uint16_t) (A | B); // compliant
A = (uint16_t) ((uint32_t)A << 1u) // compliant