MISRA-C 2012规则10.8查询

时间:2018-05-16 13:29:39

标签: c misra

我正在获取MISRA-C 2012规则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)) ) )

但是根据我的理解,在转换操作的情况下,将unsigned转换为unsigned可能不是一个好主意。

需要一些帮助...

1 个答案:

答案 0 :(得分:1)

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

  • 首先,有一些不太重要的挑选。指令4.9表示应该完全避免使用类似函数的宏。规则7.2表示必须对所有整数常量使用u后缀。

  • 这里最严重的是违反10.1,其中说&#34;移位和按位操作只应在基本上无符号类型的操作数上执行&#34; 。

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

  • 我认为没有违反10.5的规定,这会违反不合适的类型。从签名到无签名都可以。

  • 然而,您的评论表明存在违反10.8的规定 - 该规则不允许&#34;复合表达式的结果&#34;根据您的情况,从sint64_tuint64_tuint32_t转换为其他类型类别。这也可以通过在做其他事情之前转换为uint64_t 来解决。

    10.8的(相当奇怪的)基本原理是,一些初学者认为像(uint32_t)(u16a + u16b);这样的演员表示+操作是在uint32_t上执行的,这是不正确的。

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

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