繁体   English   中英

MISRA-C 2012规则10.8查询

[英]MISRA-C 2012 Rule 10.8 Query

我收到MISRA-C 2012 Rule 10.5漏洞,下面是示例代码:

++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++

typedef long long       sint64; 
typedef unsigned long long  uint64;
typedef unsigned long   uint32;

#define ntohll(x) ( ( (uint64)(ntohl( ((x << 32) >> 32) )) << 32) | ntohl( ((uint32)(x >> 32)) ) )

void main()
{
 sint64 pul_total;
 sint64 a;
 pul_total = ntohll(a); /* Rule 10.8 Violation*/    
}

++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++解决了我在下面尝试过的问题:

#define ntohll(x) ( ( (uint64)(ntohl( ((x << 32) >>(uint32)32) )) << (uint32)32) | ntohl( ((uint32)(x >>(uint32) 32)) ) )

但仍然是一个遗憾

但是,如果我像下面这样删除违规行为:

  #define ntohll(x) ( ( (uint64)(ntohl( ((x << 32) >> 32) )) << 32) | ntohl( ((uint32)((uint32)x >> 32)) ) )

但是根据我的理解,在进行移位操作时,将带符号的变量强制转换为无符号可能不是一个好主意。

同样需要一些帮助...

整个代码绝对不符合MISRA-C。

  • 首先是一些不太重要的尼特针。 指令4.9说应该完全避免类似函数的宏。 规则7.2规定您必须在所有整数常量上使用u后缀。

  • 这里最严重的是违反了10.1,它说“移位和按位运算只能在本质上无符号类型的操作数上执行”。

    您向左移动一个带符号的操作数-如果该操作数为负,则您的代码将调用未定义的行为,并且您将遇到严重的错误。 然后,您还右移带符号的操作数,如果操作数为负,则该操作数将调用实现定义的行为。 这些不仅是一些误报,而且是您必须修复的实际错误。 最简单的解决方法是在进行任何移位之前将x uint64_t转换为uint64_t

  • 我认为没有违反10.5的规定,这会导致类型不正确。 可以从有符号转换为无符号。

  • 但是,正如您的注释所指出的,违反了10.8-该规则不允许将“复合表达式”的结果sint64_t转换为其他类型类别,在您的情况下是从sint64_tuint64_tuint32_t 这也可以通过执行其他任何操作之前强制转换为uint64_t来解决。

    10.8的(有点怪异)理由是,有些初学者应该认为是诸如(uint32_t)(u16a + u16b); 表示对uint32_t执行+操作,这是不正确的。

现在真正的问题是,这些转变实际上是从一开始就试图实现的。 我不清楚。 该宏非常混乱。 如果要清除变量的某些位,则应使用位屏蔽(位& )来完成。 而且,如果必须使用未知的带符号变量的原因并且必须保留符号,则位掩码可以简单地跳过符号位。

修复此代码的最佳方法是完全重写该宏。 就目前而言,它将永远不会超过MISRA-C,这是一件好事。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM