我有这个功能:
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
是“真实”指针,我可以将0
更改为NULL
。但是numShots
是引用,我应该将其视为int
。
MISRA想要什么以及为什么?
答案 0 :(得分:4)
由于nums
是unsigned int
,因此您需要与0U
进行比较,其中附加的“U”表示文字是无符号整数,而不是有符号整数。
这一直困扰着我的团队。我们不明白为什么零需要被标记为无符号。
另外,你不是在处理指针。函数签名unsigned int&
表示变量将通过引用传递,而不是通过指针传递。您将修改原始对象,而不是副本。
答案 1 :(得分:3)
首先让我说我没有MISRA-C ++的经验,但有很多MISRA-C。
MISRA-C对于适用于MISRA-C ++的类型安全也有一些担忧。其中一个问题是不应该发生隐式类型促销。这是一个有效的问题,隐式类型促销很难理解并导致错误。大多数C和C ++程序员甚至不知道隐式类型的促销是如何工作的。为了向程序员提供有关此问题的教育并防止此类错误,有许多关于隐式类型转换/促销的MISRA规则。
其中一条规则对所有整数文字强制执行'u'后缀。规则背后的基本原理是澄清接近最大int值的大文字是无符号的,例如文字0x80000000
的类型对读者来说并不明显。 (我个人认为这个规则是多余的,有些误导,因为其他规则已经涵盖了所有隐含的转换危险。)
还有另一条规则指出针对NULL的指针检查应该是显式的。您不能写if(ptr)
,而应该写if(ptr!=NULL)
。理由是可读性和类型安全性。
显然这条规则不应该将指针与零文字进行比较。我不明白这背后的基本原理,据说他们害怕混淆指针和普通整数变量。他们显然决定偏离Bjarne Stroustrup的野心,去除C ++中的空指针。根据Stroustrup,NULL和0在C ++中总是相同的(尽管C ++ 11将有一个nullptr关键字一劳永逸地解决这个问题)。
上述规则中没有与您示例中的代码有关!您正在将参考与零文字进行比较,这是非常安全的。 MISRA检查员可能会抱怨缺少'u'后缀,但你的检查员没有。
我的结论是:
答案 2 :(得分:0)
我可能错了,我在编程方面并不是很有经验,可能答案有点迟了,但我认为你的MISRA-C检查员正在考虑“他正在将类型”参考“的变量与文字常量进行比较,所以他必须检查一个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) {
..
}
}
在此之后检查它是否在抱怨。