首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Misra和位操作

Misra和位操作
EN

Stack Overflow用户
提问于 2021-01-15 16:10:35
回答 1查看 262关注 0票数 2

我对misra和按位运算有一些理解问题。

我有以下操作:

代码语言:javascript
复制
((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执行位操作。这不是问题吗?

EN

回答 1

Stack Overflow用户

发布于 2021-01-15 17:17:19

假设32位int类型,则:

MISRA-C:2012只要求移位操作符的类型必须是“本质上无符号的”(规则10.1)。这意味着从unsigned shortint的隐式提升永远不会是有害的,因为符号位不能仅由该提升来设置。

还有进一步的要求(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都不允许的- &运算符应用了通常的算术转换。因此,需要将其修复为

代码语言:javascript
复制
(uint32_t)(some_unsigned_short >> some_unsigned_int) & 1u

或者最好是

代码语言:javascript
复制
((uint32_t)some_unsigned_short >> some_unsigned_int) & 1u

两者都是MISRA兼容的。

然而,在使用16位int的情况下,一切都会有所不同。然后,移位的unsigned short操作数将整数提升为unsigned int,而不是int,这是整数提升规则中的特殊情况(我上面给出的链接解释了这种特殊情况)。在这种情况下,在促销之后,我们最终使用some_unsigned_int >> ...,这是很好的。然后(some_unsigned_int >> ...) & 1u也没问题。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65732536

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档