2013-03-05 77 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) { 
     .. 
    } 
} 

檢查它是否是後抱怨。