目錄
一、MISRA C簡介
二、聲明與定義
1. 必需。類型應被顯式聲明。
2. 必需。函數應以原型形式命名參數。
3. 必需。所有對象和函數的聲明需要使用完全相同的名字和參數。
4. 必需。當定義有外部鏈接的對象或函數時,兼容聲明應是可見的。
5. 必需。外部變量或函數應被在僅一個文件內被聲明過。
6. 必需。有外部鏈接的標識符應有一個確切的外部定義。
7. 建議。若函數和對象僅被一個單元引用,最好不定義外部鏈接。
8. 必需。靜態存儲類說明符應在所有具有內部鏈接的對象和函數的聲明中使用。
9. 建議。如果一個對象的標識符僅在一個函數內出現,該對象應被定義在塊范圍內。
10. 必需。內聯函數定義時應用靜態存儲類聲明。
11. 建議。當有外部鏈接的數組被定義,應顯式指定其大小。
12. 必需。枚舉列表內的枚舉值應獨一無二。
13. 建議。指針最好指向一個const類型的變量。
14. 必需。不得使用restrict限定詞。
?相關文章如下:
1、《MISRA C-2012準則之標準C環境準則》
2、《MISRA C-2012準則之未使用的代碼的處理》
3、《MISRA C-2012準則之注釋》
4、《MISRA C-2012準則之標識符》
5、《MISRA C-2012準則之常量》
6、《MISRA C-2012準則之聲明與定義》
7、《MISRA C-2012準則之初始化》
8、《MISRA C-2012準則之基本數據類型》
9、《MISRA C-2012準則之指針類型轉換》
10、《MISRA C-2012準則之表達式》
一、MISRA C簡介
MISRA C是由汽車產業軟件可靠性協會(MISRA)提出的C語言開發標準。其目的是在增進嵌入式系統的安全性及可移植性。
MISRA C一開始主要是針對汽車產業,不過其它產業也逐漸開始使用MISRA C:包括航天、電信、 ?國防、醫療設備、鐵路等領域中都已有廠商使用MISRA C。
MISRA C的第一版是在1998年發行,一般稱為MISRA-C:1998。在2004年時發行了第二版的MISRA C,稱作MISRA-C:2004。2012年發布第三版,為當前最新有效的C語言規范版本,稱為MISRA-C:2012。 MISRA C不能100%保證程序不出問題,但是能盡可能的預防,總結一下,基本上使用MISRA C具有以下五個維度的優勢:
1、提升可靠性
2、提升可讀性
3、提升可移植性
4、提升可維護性
5、提升安全性
二、聲明與定義
必需。類型應被顯式聲明。
必需。函數應以原型形式命名參數。
必需。所有對象和函數的聲明需要使用完全相同的名字和參數。
必需。當定義有外部鏈接的對象或函數時,兼容聲明應是可見的。、
必需。外部變量或函數應被在僅一個文件內被聲明過。
必需。有外部鏈接的標識符應有一個確切的外部定義。
建議。若函數和對象僅被一個單元引用,最好不定義外部鏈接。
必需。靜態存儲類說明符應在所有具有內部鏈接的對象和函數的聲明中使用。
建議。如果一個對象的標識符僅在一個函數內出現,該對象應被定義在塊范圍內。
必需。內聯函數定義時應用靜態存儲類聲明。
建議。當有外部鏈接的數組被定義,應顯式指定其大小。
必需。枚舉列表內的枚舉值應獨一無二。
建議。指針最好指向一個const類型的變量。
必需。不得使用restrict限定詞。
1. 必需。類型應被顯式聲明。
#include <stdio.h>int main() {a = 10; // 錯誤:變量a未顯式聲明printf("%d\n", a);return 0;
}
2. 必需。函數應以原型形式命名參數。
#include <stdio.h>int add(); // 錯誤:函數原型未命名參數int main() {printf("%d\n", add(5, 3));return 0;
}int add(int a, int b) {return a + b;
}
3. 必需。所有對象和函數的聲明需要使用完全相同的名字和參數。
#include <stdio.h>int func(int a); // 聲明
int func(float a); // 錯誤:函數聲明參數類型不一致int main() {printf("%d\n", func(5));return 0;
}int func(int a) {return a;
}
4. 必需。當定義有外部鏈接的對象或函數時,兼容聲明應是可見的。
#include <stdio.h>int globalVar; // 聲明int main() {printf("%d\n", globalVar);return 0;
}// 錯誤:外部變量globalVar的定義不可見
// int globalVar = 10;
5. 必需。外部變量或函數應被在僅一個文件內被聲明過。
// file1.c
int globalVar = 10;// file2.c
#include <stdio.h>int main() {printf("%d\n", globalVar);return 0;
}// 錯誤:globalVar在多個文件中定義
// int globalVar = 20;
6. 必需。有外部鏈接的標識符應有一個確切的外部定義。
#include <stdio.h>int globalVar; // 聲明int main() {printf("%d\n", globalVar);return 0;
}// 錯誤:globalVar沒有外部定義
7. 建議。若函數和對象僅被一個單元引用,最好不定義外部鏈接。
#include <stdio.h>int globalVar = 10; // 外部鏈接int main() {printf("%d\n", globalVar);return 0;
}// 建議:如果globalVar僅被main函數使用,應定義為靜態
// static int globalVar = 10;
8. 必需。靜態存儲類說明符應在所有具有內部鏈接的對象和函數的聲明中使用。
#include <stdio.h>int func(); // 錯誤:函數聲明未使用靜態存儲類int main() {printf("%d\n", func());return 0;
}int func() {return 10;
}
9. 建議。如果一個對象的標識符僅在一個函數內出現,該對象應被定義在塊范圍內。
#include <stdio.h>int globalVar = 10; // 全局變量int main() {printf("%d\n", globalVar);return 0;
}// 建議:如果globalVar僅被main函數使用,應定義為局部變量
// int main() {
// int localVar = 10;
// printf("%d\n", localVar);
// return 0;
// }
10. 必需。內聯函數定義時應用靜態存儲類聲明。
#include <stdio.h>inline int add(int a, int b) { // 錯誤:內聯函數未使用靜態存儲類return a + b;
}int main() {printf("%d\n", add(5, 3));return 0;
}
11. 建議。當有外部鏈接的數組被定義,應顯式指定其大小。
#include <stdio.h>int globalArray[] = {1, 2, 3}; // 錯誤:外部鏈接數組未顯式指定大小int main() {printf("%d\n", globalArray[0]);return 0;
}
12. 必需。枚舉列表內的枚舉值應獨一無二。
#include <stdio.h>enum Colors {RED,GREEN,BLUE,RED // 錯誤:枚舉值RED重復
};int main() {return 0;
}
13. 建議。指針最好指向一個const類型的變量。
#include <stdio.h>int main() {int a = 10;int *ptr = &a; // 錯誤:指針未指向const類型變量printf("%d\n", *ptr);return 0;
}
14. 必需。不得使用restrict限定詞。
#include <stdio.h>void func(int * restrict a, int * restrict b) { // 錯誤:使用了restrict限定詞*a = 10;*b = 20;
}int main() {int x, y;func(&x, &y);printf("%d %d\n", x, y);return 0;
}