User Tools

Site Tools

blog:2024-03-21_reference_misra_c_2004規範標準



2024-03-21 Reference: MISRA C 2004規範標準

  • Refer here, there is the MISRA C 2004 standard description

Local Backup

  • 以下為MISRA C 2004規範標準。
  • <環境>
    • 規則1.1(強制):所有的程式碼應該遵守ISO 9899:1990「Programming Language C」
    • 規則1.2(強制):只有當具備統一介面的目標程式碼的時候才可以採用多種編譯器和語言。
    • 規則1.4(強制):檢查編譯器/ 連接器以確保支援31 一個有效字符,支援大小寫敏感。
  • <語言擴充>
    • Rule 2.1(強制):組合語言應該封裝起來並且隔離。
      • 例如:#define NOP asm( “NOP”)
    • 規則2.2(強制):原始碼只能採用/* …*/風格的註解。
    • 規則2.3(強制):字元序列/* 不能在註解中使用。
      • 註:C 語言不支援註解的巢狀即使一些編譯器支援這個語言擴充。
    • 規則2.4(建議):程式碼段不能註解掉。
      • 註:應採用#if 或#ifdef 來構成一個註釋,否則程式碼裡如果有註解會改變程式碼的作用。
  • <文檔化>
    • 規則3.3(建議):編譯器對於整數除法運算的實作應該寫入文件。
      • 例: -5/3 = -1 餘-2 有些編譯器結果是-2 於+1。
  • <字元集>
    • 規則4.1(強制):只能使用ISO 標準定義的字元集。
  • <識別符>
    • 規則6.5 (強制):在內部範圍的識別碼不能和外部的識別碼用同樣的名字,因為會隱藏那個識別符。
      • 例:
        int16_t i: 
        void f() 
        { 
            int16_t i; 
            i=3 ;
        }
    • 規則5.2(強制):typedef 名稱只能唯一,不能重複定義。
    • 規則5.4(強制):標記名應該是唯一的識別碼。
    • 規則5.7(建議):標識符不能重複使用。
  • <類型>
    • 規則6.1(強制):char 類型只能用來儲存使用字元。
    • 規則6.2(強制):signed 和unsigned char 只能用來儲存和使用資料值
    • 規則6.3(建議):對於基本資料類型,必須使用typedef明確標識出資料長度。
      • 例:
        typedef signed char int8_t;
        typedef unsigned int uint16_t;
  • <約束>
    • 規則7.1(強制):禁止使用八進位數(0除外)或八進位轉義字元。
      • 註:整數常數以」0開始會被認為是八進位。
      • 例:
        code[1]=109 
            code[2]=100 
            code[3]=052 
      • 如果是對總線訊息初始化,會有危險。
  • <聲明與定義>
    • 規則8.1(強制):函數都應該有原型聲明,且相對函數定義和呼叫可見。
    • 規則8.2(強制):無論何時一個物件和函數宣告或定義,它的類型應該明確聲明。
    • 規則8.3(強制):函數宣告中的參數型別應該和定義中的型別一致。
    • 規則8.4(強制):如果物件或函數被聲明了多次,那麼它們的類型應該是相容的。
    • 規則8.5(強制):頭檔中不應定義物件或函數。
    • 規則8.6(強制):函數應該聲明為具有檔案作用域。
    • 規則8.7(強制):如果物件的存取只是在單一的函數中,那麼物件應該在區塊範圍內聲明。
    • 規則8.8(強制):外部變數或函數只能宣告在一個檔案中。
    • 規則8.9(強制):具有外部連結的識別碼應該具有準確的外部定義。
    • 規則8.10(強制):在文件範圍內聲明和定義的所有對像或函數具有內部鏈接,除非是在需要外部鏈接的情況下。
    • 規則8.11(強制):static儲存類別標識符應該用於具有內部連結物件和函數的定義和聲明。
    • 規則8.12(強制):數組宣告為外部,應該明確聲明大小或直接初始化確定。
  • <初始化>
    • 規則9.1(強制):所有變數在使用前都應該賦值。
    • 規則9.2(強制):應該使用大括號一指示和匹配數組和結構的非零初始化構造。
    • 規則9.3(強制):在枚舉列表中,”=“不能明確用於除首元素之外的元素上,除非所有的元素都是明確初始化的。
  • <數學型別轉換(隱式)>
    • 規則10.1(強制):整數運算式不要隱式轉換成其他型別。
      • 1)轉換到更大的整型。
      • 2)表達式太複雜。
      • 3)表達式不是常數是一個函數。
      • 4)表達式不是一個常數是一個返回表達式。
    • 規則10.2(強制):浮點數表達式不要隱式轉換為其他型別。
      •   1)轉換到更大的浮點數。
      •   2)表達式太複雜。
      •  3)表達式是一個函數。
      •  4)表達式是一個返回表達式。
  • <數學型別轉換(明確)>
    • 規則10.3(強制):整數運算式的值只能轉換到更窄小且是同樣符號型別的表達式。
    • 規則10.4(強制):浮點表達式的值只能轉換到更窄小的浮點表達式。
    • 規則10.5(強制):如果位元運算~和«套用在基本型別為unsigned char 或unsigned short的運算元,結果應該立即強制轉換為預期運算元的基本型別。
      • 例:
        uint8_t a = 0x5a;
        uint8_t b;
        b = ((uint8_t)(~a))>>4;
  • <數學型別轉換>
    • 規則10.6(強制):所有的unsigned 類型都應該有後綴「U」。
    • 規則11.1(強制):指標不能轉換為函數或整型以外的其他型別。
  • <表達式>
    • 規則12.2(強制):表達式的值應和標準允許的評估順序一致。
      • 例:
        x=b[i] + i++;
        • 不同的編譯器給的結果不一樣,b[i] 是否先執行?
        • 應:x=b[i]; i++;
        • 例如:
          x=func(i++,i);
    • 規則12.3(強制):sizeof 運算子不能用在包含邊界作用(side effect) 的表達式上。
      • 例:
        int32_t=i;
        int32_t=j;
        j=sizeof(i=1234);
      • 表達式並沒有執行,只是得到表達式型別int的size。
    • 規則12.4(強制):邏輯運算子&& 或||右邊不能包含邊界作用(side effect)。
      • 例:
        if(ishight) && (x== i++)), 如果ishight =0 那麼i++不會評估
    • 規則12.5(建議):++和- - 不能和其他表達式用在一個表達式中。
      • 例:
        u8a=++u8b + u8c–;
  • <控制語句表達式>
    • 規則13.1(強制):賦值語句不能用在一個產生布林值的表達式中。
      • 例:
        if((x=y)!=0) …
        if (x=y) …
    • 規則13.3(強制): 浮點表達式不應該測試其是否相等或不相等。
    • 規則13.4(強制):for控製表達式中不要包含任何浮點類型。
    • 規則13.6(強制):數字變數作為for迴圈的迴圈計數不要在迴圈體內部被修改。
      • 例:
        flag=1; 
        for(i=0;(i<5)&&(flag==1);i++) 
        { 
          flag=0; 
          i=i+3; 
        } 
  • <控制流程>
    • 規則14.1(強制):不要有執行不到的程式碼。
      • 例:
        swich(event) 
        { 
        case 0; 
              do_wakeup(); 
              break; 
              do_more(); 
        … 
        } 
    • 規則14.4(強制) :goto 語句不能使用。
    • 規則14.5(強制):continue 不能使用。
    • 規則14.6(強制): 函數應在函數結束有一個出口。
    • 規則14.7(強制):witch、while do 、while for 語句體應為混合語句。
    • 規則14.10(強制): 所有if else if 結構都應該由else 結束。
      • switch(x) 
        { 
        uint8_t var; /* 违反*/ 
        case 0:  
        … 
        } 
  • <函數>
    • 規則16.2(強制): 函數不能直接或間接的呼叫自己。
      • 例:系統不能用遞歸,超出堆疊空間很危險。
    • 規則16.8(強制):non-void 類型函數的所有出口路徑都應該有明確的return 語句表達式。
  • <指標與陣列>
    • 規則17.1(強制):指標的數學運算只能用在指向陣列的位址上。
    • 規則17.3(強制):>,>=,<,⇐ 不能用在指標類型,除非指向同一個陣列。
    • 規則17.5(建議):禁止使用2 級以上指針。
  • <結構與聯合>
    • 規則18.4(強制):禁止使用union(共用體)。
  • <預處理指令>
    • 規則19.1(建議):#include 語句的前面只能有其他預處理指令和註解。
    • 規則19.2(建議):#include 指令中的頭檔名稱不能包含非標準的字元。
    • 規則19.5(強制):巨集不能在函數體內定義。
    • 規則19.8(強制):類別函數宏呼叫時不能沒有它的參數。
  • <標準函式庫>
    • 規則20.1(強制):標準函式庫中的保留標識符,巨集和函數不能定義,重定義和undefined。
    • 規則20.4(強制):動態記憶體分配不能使用。
      • 例:不能使用malloc、calloc、free、realloc。
    • 規則20.9(強制):輸入輸出庫(stdio.h) 不能用在產生嵌入式系統。
    • 規則20.12(強制):時間處理函數time.h不能使用。
  • <運行時故障>
    • 規則21.1(強制):透過使用以下手段確保把運行時故障最小化。
      •  1)靜態分析工具/技術。
      •  2)動態分析工具/技術。
      •  3)編寫明確的程式碼避免執行時錯誤。

TAGS

  • 35 person(s) visited this page until now.

Permalink blog/2024-03-21_reference_misra_c_2004規範標準.txt · Last modified: 2024/03/21 10:31 by jethro

oeffentlich