关注+星标公众号,不错过精彩内容!
MISRA是汽车工业软件可靠性联合会的简称(The Motor Industry Software Reliability Association),此协会致力于规范汽车厂商开发安全可靠的软件,其重要成果就是MISRA规范,最开始MISRA规范主要应用在汽车领域,用于提高嵌入式代码的健壮性、稳定性、可移植性等等。后来在航空航天、医疗器械,工业控制等行业得到了广泛的应用。MISRA包含两个标准一个是MISRA C,另外一个是MISRA C++,分别针对C语言与C++语言,是目前十分流行的嵌入式编程规范。
C语言是应用十分广泛的语言,尤其在嵌入式系统(单片机、ARM)优势十分明显,但是C语言中存在很多“缺陷”。这些缺陷基本上可以分为三类:
1、未定义行为(undefined behaviour)
是指C语言标准中没有具体定义的C语言操作。未定义行为编译器往往自行处理,可能不会报告错误,或者只报告警告,不同的编译器表现出不同的编译结果,什么状况都有可能发生,我们在编写代码时要避开这个雷区,如下:
int val = 5;
return val / 0; /* undefined behavior */
int arr[4] = {0, 1, 2, 3};
return arr[5]; /* undefined behavior for indexing out of bounds */
val = 0;
int ptr = *val; /* undefined behavior for dereferencing a null pointer */
char* s = "geeksforgeeks";
s[0] = 'e'; /* undefined behavior */
int* ptr = NULL;
printf("%d", *ptr); /* undefined behavior for accessing NULL Pointer */
2、未指定行为(unspecified behaviour)
在C语言标准中规定了多种可能的行为,每一种都是符合标准的,但是具体执行哪一种没有指定。我们编写代码时,使用不同的编译器可能会出现不同的结果,因为编译器选择的行为可能不同。
x = fun1() + fun2(); /* 两个函数执行先后循序未指定*/
x = func( i++, i ); /* 两个参数先执行哪个未指定 */
x = b[i] + i++; /* 同上 */
3、实现定义行为(implementation defined behaviour)
C语言标准没有规定,由编译器去实现,不同的编译器实现方法不同。如果代码中使用实现定义的代码,那么这种代码的可移植性不好。例如不同编译器对有符号整数右移操作时,对符号位的处理也是实现定义的。位域中元素跨越存贮单元的边界时,不同编译器的实现方法不一样。位域中的元素在内存的排列顺序,对齐方式都是实现定义的,编译器厂自由发挥。
struct message
{
unsigned int a: 10;
unsigned int b: 20;
/* a+b+c超过了一个存储单元,大部分编译器会把C存储到下一个单元,
但是在C语言规范中是实现定义的,让编译器厂自由发挥 */
unsigned int c: 5;
} msg;
MISRA规范对以上各种缺陷都做了严格限定,否则这些缺陷一旦暴雷,那就是致命错误。代码遵从MISRA规范能够提升代码健壮性以及可移植性。