最近接触了代码静态检查工具QAC以及PolySpace,在使用过程中积累了一些经验,在此记录。
一、类型问题
可以说是最多的一类问题。
1、常量需要注明类型
uint32 i = 0; /*i是无符号数,与它比较的0要明确申明为无符号数0u*/ if( i > 0u){ func1(); }
2、enum(包括其他自定义类型)不能与数据类型(uint8 uint16 uint32 sint8 sint16 sint32等)互相转换
typedef enum{ ENUM0, ENUM1 }TempEnum; TempEnum e = ENUM0; uint8 i = 0;
/*以下行为都禁止*/ i = e; i = (uint8)e; e = i; e = (TempEnum)i;
3、赋值操作时右值要强制转换成与左值相同的类型。
二、控制流问题
1、所有 if else 最后都需要一个 else 处理其他情况,哪怕什么都不做也要在语义上说明自己“考虑”到了其他情况;
1 if(xxx){ 2 func1(); 3 }else if(xx){ 4 func2(); 5 }else{ 6 /*nothing*/ 7 }
三、关键字问题
1、不允许使用union
四、指针问题
1、在指针操作数上由算术运算得到的指针应指向与指针操作数相同的数组的元素。
while(len > 0u){ /*bad*/ *dest++ = *src++; } for(i = 0; i<len; i++){ /*good*/ dest[i] = src[i]; }
2、禁止使用指针操作结构体连续内存
struct TempStruct { uint8 byte1; uint8 byte2; }testStruct; uint8 *p = &testStruct->byte1; /*禁止*/ for(i = 0u; i < 2u; i++){ p[i] = 0; }
未解之谜?
1、PolySpace下返回枚举类型的函数与枚举变量类型比较会判断为类型不匹配,需要对枚举变量做强制类型转换
typedef enum{ ENUM0, ENUM1 }TempEnum; TempEnum func1(void); /*ENUM0的强制类型转换不可少*/ if(func1() == (TempEnum)ENUM0)
2、PolySpace会把switch分支里的default标号下的代码判为不可达