目录
一、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;
}