我对misra和按位运算有一些理解问题。
我有以下操作:
((in >> bit) & 1u)这里,in的类型是unsigned short,而bit的类型是int。在我的理解中,1u应该是一个unsigned int。
首先,我不明白为什么misra不抱怨位移位是用不同类型的带符号的bit完成的,我也不明白为什么允许unsigned short之间的位操作,这应该是(in >> bit) & 1u的结果。
更新是为了澄清这样一个问题:为什么允许bit的类型不同于in?
它不应该导致不匹配的类型吗?
如果我将32位1的bit移位到16位的in,会不会不会有问题?
也是第二部分。位移位的结果是unsigned short,因此使用16位short和32位int执行位操作。这不是问题吗?
发布于 2021-01-15 17:17:19
假设32位int类型,则:
MISRA-C:2012只要求移位操作符的类型必须是“本质上无符号的”(规则10.1)。这意味着从unsigned short到int的隐式提升永远不会是有害的,因为符号位不能仅由该提升来设置。
还有进一步的要求(MISRA-C:2012规则10.4),执行“常用算术转换”(参见Implicit type promotion rules)的表达式中的两个操作数应该属于相同的基本类型类别。“一如既往……”适用于C中的大多数二元运算符,但不适用于移位运算符,它们是一个特例。
对于移位运算符,C标准6.5.7列出了这个特殊规则:
在每个操作数上执行整数提升。结果的类型是提升的左操作数的类型。
这意味着some_unsigned_short >>是MISRA-C兼容的,并且bit的类型实际上是无关紧要的(只要它是一个正数)。然而,规则10.1要求正确的操作数也必须是无符号的(以防止像>> -1这样的胡说八道的东西)。即使右操作数也是无符号的,表达式仍然有点问题-最好在移位之前将左操作数转换为大整数类型(如uint32_t)。
忽略移位的右操作数,(some_unsigned_short >> some_int) & 1u仍然不符合MISRA-C,因为它混合了有符号和无符号的基本类型类别int & unsigned int,这是规则10.1和规则10.4都不允许的- &运算符应用了通常的算术转换。因此,需要将其修复为
(uint32_t)(some_unsigned_short >> some_unsigned_int) & 1u或者最好是
((uint32_t)some_unsigned_short >> some_unsigned_int) & 1u两者都是MISRA兼容的。
然而,在使用16位int的情况下,一切都会有所不同。然后,移位的unsigned short操作数将整数提升为unsigned int,而不是int,这是整数提升规则中的特殊情况(我上面给出的链接解释了这种特殊情况)。在这种情况下,在促销之后,我们最终使用some_unsigned_int >> ...,这是很好的。然后(some_unsigned_int >> ...) & 1u也没问题。
https://stackoverflow.com/questions/65732536
复制相似问题