2013-03-05 38 views
4

我有这样的功能:文字零,而不是空指针常数警告由MISRA

void InitS(unsigned int &numS){ 
    // this function returns a container for unsigned int 
    // but it has a cast for int 
    numS = props.numOfS(); 
    if (numS > 0) { 
     .. 
    } 
} 

它编译,但给了我这个MISRA警告:

MISRA-C++规则4-10- 2(必需):文字零(0)不能用作空指针常量。现在

,如果numShots是一个“真正的”指针我可能已经改变0NULL。但numShots是参考,我应该把它当作int

MISRA需要什么?为什么?

+2

看起来像一个bug给我。 – PlasmaHH 2013-03-05 15:42:44

+0

如果这是代码的正确表示,那么我同意,那里没有错误。 – 2013-03-05 15:43:01

+0

你确定'if(numS> 0)'是产生警告的行吗? – Angew 2013-03-05 15:43:33

回答

4

由于numsunsigned int,您需要与0U进行比较,其中附加的'U'表示文字是无符号整数,而不是带符号整数。

这让我的团队陷入困境。我们不明白为什么零需要标记为无符号。

此外,你不处理指针。函数签名unsigned int&指示变量将通过引用传递,而不是通过指针传递。您将修改原始对象,而不是副本。

+0

我还是不明白为什么misra抱怨不使用空指针常量,如果你说什么实际上是问题? – 2013-03-05 16:10:19

+0

MISRA是非常严格的类型检查,超过了正常的编译器选项。变量不应与指针常量进行比较。指针不应与数字文字进行比较。 – 2013-03-05 17:30:40

+0

所以0是有符号int?那为什么MISRA认为它的空指针是常量?这似乎很奇怪的行为,因为NULL在C++中实现为((void *)0),所以为什么MISRA不会抱怨如果numS是有符号int? – 2013-03-06 06:52:48

3

让我首先说我没有MISRA-C++的经验,但是大量的MISRA-C。

MISRA-C对于适用于MISRA-C++的类型安全性也有一些担忧。其中一个担忧是不应该发生隐式类型的促销活动。这是一个有效的担忧,隐式类型的促销很难理解并导致错误。大多数C和C++程序员令人惊讶地甚至不知道隐式类型促销如何工作。为了向程序员提供这方面的教育并防范此类错误,有许多关于隐式类型转换/促销的MISRA规则。

  • 一个这样的规则强制所有整数文字的'u'后缀。该规则背后的基本原理是澄清接近最大整数值的大文字是无符号的,例如文字0x80000000的类型对读者来说并不明显。 (我个人认为这个规则是多余的,有些误导,因为其他规则已经涵盖了所有隐含的转换危险。)

  • 还有另一个规则,指出针对NULL的指针检查应该是显式的。你不能写if(ptr),你应该写if(ptr!=NULL)。理由是可读性和类型安全性。

  • 而且显然这个规则指针不应该与零字面值进行比较。我不明白这背后的基本原理,据说他们担心你混合了指针和纯整数变量。他们显然已经做出决定,偏离了Bjarne Stroustrup的雄心,使C++中的空指针去神秘化。根据Stroustrup的说法,NULL和0在C++中总是等价的(尽管C++ 11将有一个nullptr关键字来解决这个混乱问题)。

无的上述规则有什么在你的例子代码!您正在比较一个参考与零文字,这是完全安全的。 MISRA检查员可能会抱怨缺少'u'后缀,但您的检查员没有。

我的结论是:

  • 你MISRA-C++检查故障并给出了不正确的错误。
  • 针对文字零的特定MISRA-C++规则似乎没有任何意义。您应该根据这个规则在您的MISRA实施中提出偏差,并且完全忽略该规则,直到有人能够为其提供理由。
0

我可能是错的,我在编程方面并不是很成熟,可能答案有点晚,但我认为你的MISRA-C检查器在考虑“他正在比较类型为”reference“的变量一个字面常量,所以他必须检查一个NULL引用“,尽管它对于引用并不是真的有效,但是你可以尝试将函数props.numOfS()的返回值赋给一个新变量,然后对变量赋值在对新变量进行比较时,由另一行中的numS引用。

void InitS(unsigned int &numS){ 
    unsigned int foo; 
    foo = props.numOfS(); //this function returns a container for unsigned int but it has a cast for int 
    numS = foo; 
    if (foo > 0) { 
     .. 
    } 
} 

检查它是否是后抱怨。