簡體   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