首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >位算子的Misra违反

位算子的Misra违反
EN

Stack Overflow用户
提问于 2015-12-02 10:31:01
回答 2查看 1.4K关注 0票数 4

我编写了MISRA不喜欢的以下代码:

代码语言:javascript
复制
UartPtr->C &= ((uint8_t)(~SIO_C2_SBK));

使用

代码语言:javascript
复制
#define SIO_C2_SBK ((uint8_t)0x01u)

UartPtr被定义为

代码语言:javascript
复制
UartPtr = (UartStruct*) 0x12345678; /* I know that this is also a violation of MISRA */

使用底层数据结构:

代码语言:javascript
复制
typedef volatile struct UartStructTag
{
  uint8_t      BDH;
  uint8_t      BDL;
  uint8_t      C1;
  uint8_t      C2;
} UartStruct;

我的米斯拉检验员抱怨第一行,并说

带有负值的整数常量表达式正在转换为无符号类型。

然而,以下行并没有出现MISRA的问题:

代码语言:javascript
复制
UartPtr->C |= ((uint8_t)(SIO_C2_SBK));

所以问题来自于按位否定。但是由于所有的操作都是直接抛给uint8_t的,所以我没有得到对MISRA标准的违反。谁想在这里帮我?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-12-02 10:35:01

在任何算术表达式中,小于int的类型的值在处理它们之前都被隐式转换为int。C语言不能对小于int的类型执行算术。因此,您的代码实际上的行为如下:

代码语言:javascript
复制
UartPtr->C &= ((uint8_t)(~(int)(uint8_t)0x01u));

这才是

代码语言:javascript
复制
UartPtr->C &= ((uint8_t)(~1));

其中,~1在两个互补体系结构上具有值-2

若要解决此问题,请在按位不应用之前转换为unsigned或任何其他大于int的无符号类型:

代码语言:javascript
复制
UartPtr->C &= ((uint8_t)(~(unsigned)SIO_C2_SBK));
票数 6
EN

Stack Overflow用户

发布于 2015-12-02 10:51:08

与大多数C运算符一样,~运算符将在应用运算符之前对操作数进行隐式整数转换。

代码语言:javascript
复制
#define SIO_C2_SBK ((uint8_t)0x01u)

因此,上面的宏就是问题所在,因为您正在强制将文本从unsigned int类型降为小整数类型,这将得到隐式提升。在应用uint8_t之前,您可以使用int代替~

这违反了MISRA-C:2004的规则10.1,该规则不允许产生不同符号类型的隐式转换(这种转换是危险的,因此是非常好的规则)。

  • 如果您不需要这个宏来给uint8_t,那么简单地放弃(uint8_t强制转换,这将解决问题。
  • 如果由于某种原因,这个宏必须给uint8_t,那么将代码更改为以下代码(符合MISRA标准): UartPtr->C &= (uint8_t) ~(uint32_t)SIO_C2_SBK; 其中uint32_t对应于给定平台上int的大小。
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34040433

复制
相关文章

相似问题

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