簡體   English   中英

MISRA C-2012 規則 10.3 由於添加兩個 8 位變量而導致 32 位

[英]MISRA C-2012 Rule 10.3 violation due to adding of two 8 bit variables which resulted in 32 bit

我收到 MISRA C-2012 規則 10.3 違規:以下代碼的“var4 + var5”從基本類型有符號 32 位 int 到不同或更窄基本類型無符號 8 位 int 的隱式轉換。

int8_t var4 = -10;
uint8_t var5 = 15;
uint8_t var6 = var4 + var5;

“var4 + var5”如何解釋為 32 位 int,因為每個都是 8 位大小。

還有什么是解決這個問題的正確方法?

這是由於整數促銷而發生的。 這在C 標准的第 6.3.1.1 節中有詳細說明

2可以在可以使用intunsigned int的表達式中使用以下內容:

  • 具有整數類型(除了intunsigned int )的對象或表達式,其整數轉換等級小於或等於in t 和unsigned int的等級。
  • _Boolintsigned intunsigned int類型的位域。

如果int可以表示原始類型的所有值(受寬度限制,對於位域),則該值將轉換為int 否則,它被轉換為unsigned int 這些被稱為整數提升。 整數提升不會改變所有其他類型。

因為int8_tuint8_t等級低於int ,所以這些類型的變量在表達式中使用時會提升為int 如果是:

uint8_t var6 = var4 + var5;

var4var5都被提升為int ,並且+運算符的結果也是int類型。 然后var6值分配回var6 ,它是一個uint8_t ,這可能導致值被截斷。

處理此問題的最佳方法是首先驗證結果不會溢出,然后顯式轉換結果:

uint8_t var6 = (uint8_t)(var4 + var5);

原因是隱式類型促銷 在那一行中有3個隱含的促銷,這是危險和草率的風格。 您可以在一行代碼中同時進行整數提升/通常的算術轉換和隱式左值轉換。

您必須了解這些覆蓋如何在 C 中工作,以便編寫無錯誤的 C 代碼,但您還必須了解它們才能使用 MISRA-C。 事實上,MISRA-C 的目的之一一直是就隱式類型提升對程序員進行教育——您還可以在 MISRA-C 文檔中找到解釋。

您的代碼實際上違反了多項 MISRA-C:2012 規則。 不僅 10.3 關注隱式左值轉換,還有 10.4:

執行通常算術轉換的運算符的兩個操作數應具有相同的基本類型類別。

var4本質上是有符號的, var5本質上是無符號的。 因此,僅僅將結果轉換為適當的類型是不夠的。 要獲得符合 MISRA-C 的代碼,您必須將兩個操作數強制轉換為相同類型。 或者更好的是,首先使用適當類型的變量:將-10 + 15的結果存儲在無符號變量中沒有多大意義。 您要么需要簽名號碼,要么不需要。

要獲得完全可移植的 MISRA-C 兼容代碼,這應該是一種無法隱式提升的類型,例如uint32_t

uint8_t var6 = (uint8_t) ((uint32_t)var4 + (uint32_t)var5);

或者

int8_t var6 = (int8_t) ((int32_t)var4 + (int32_t)var5);

這個表達式是粗獷、專業的 C,因為它不包含一個隱式提升。 它是自記錄代碼,因為它表明程序員知道並考慮過隱式類型提升。 影響性能相比僅具有8位操作數的表達,因為編譯器可以自由地優化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM