MISRA-C 2004 规则解读

MISRA-C 2004 规则解读

Written By Tomy Stark.
E-mail: ro7enkranz@qq.com
Ver 1.0.0

Note:

  • 本标准会不定期迭代完善
  • 本文档由我从互联网整理收集而来,尚需完善,文中可能还存在诸多谬误,若发现有误可邮件联系以修正问题,在此感谢!

1 S ~ 20 S

1 S:Procedure name reused.函数名与变量名称重复。

2 S:Label name reused.局部变量重命名。虽然作用域不同能编译通过,但是容易造成混淆。

3 S:More than N executable reformatted lines in file.规定单个文件代码行数不能超过N,N值可配置。

4 S:Procedure exceeds N reformatted lines.规定单个函数的代码行数不能超过N,N值可配置。

5 S:Empty then clause.空语句有可能是开发人员忘记实现某个功能而留下的坑。所以在确实是空的地方这样写比较合适:

1
2
3
4
5
6
7
UINT_32 value_x = 1u;

if (value_x == 0u) {
value_x = value_x + 1u;
} else
/*do nothing*/

6 S:Procedure pointer declared.避免使用函数指针:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "c_standards.h"
void foo(UINT_32 p_1, UINT_16 p_2)
{ /* ... */ }

/********************************************************
* Standard 6 S : Procedure pointer declared.
********************************************************/

void static_6(void)
{
void (*proc_pointer) (UINT_32 p_1, UINT_16 p_2) = foo; /* 不建议使用函数指针 */

proc_pointer(1u, 1);
}

7 S:Jump out of procedure. 避免使用非局部跳转语句,如setjmp和longjmp函数。

8 S:Empty else clause. 见【5S】。

9 S:Assignment operation in expression. 避免在表达式中使用赋值语句,举个栗子:

1
2
3
4
5
6
BOOL static_9(BOOL test)
{
BOOL result,flag;
result = ( flag = test ); /* not compliant */
return result;
}

10 S:空

11 S:No brackets to loop body (added by Testbed). 避免省去大括号,举个栗子:

1
2
3
4
5
6
for (i = 0; i < 10; i = i + 1) j--; /* not compliant */

if (i > 0) {
i = i - 1;
} else
i = i + 1; /* not compliant */

12 S:No brackets to then/else (added by Testbed). 见【11S】。

13 S:goto detected.避免使用goto语句。

14 S:Procedural parameter declared. 避免使用函数作为函数的参数。

1
2
3
4
5
6
7
/********************************************************
* Standard 14 S : Procedural parameter declared.
********************************************************/
void static_14(void (*p_proc_pointer)(INT_32 p1))
{
p_proc_pointer = test_14s;
}

15 S:Anonymous field to structure. 避免使用无名称的结构体,这通常出现在结构体嵌套使用的场景。

1
2
3
4
5
6
7
8
9
10
11
/********************************************************
* Standard 15 S : Anonymous field to structure.
********************************************************/

struct s_15 {
UINT_32 xs;
struct {
UCHAR ac;
UCHAR ab;
}; /* not compliant */
};

16 S:Multiple labels declared. 避免在文件的同一处使用多个标签。

17 S:Code insert found. 避免在代码中嵌套出现汇编语句,大多数编译器是编译不通过的。

18 S:More than N parameters in procedure. 规定单个函数入参个数不能超过N,N值可配置。

19 S:Procedural para used in an uncalled procedure. 避免函数作为参数的情况,即使该函数未被调用,同【14S】。

20 S:Parameter not declared explicitly. 避免入参无变量类型,大多数编译器是编译不通过的。

21 S ~ 40 S

21 S:Number of parameters does not match. 函数定义的入参的个数与使用时传入的入参个数不一致。

22 S:Use of obsolete language feature ( use = - ). 不应当使用早期C语言中存在的语法规则,如=- =* =+等运算符。

23 S:Procedure is not called in text analysed. 在main函数的源文件中,如果某个函数不被本文件调用,该函数放在其他的源文件中比较合适。

24 S:Use of Noanalysis annotation. 使用标记某段源代码,这段代码不会被进行静态规则检查。

25 S:Null case(s) in switch statement. 避免某个case语句为空而执行到了下一个case:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
INT_32 static_25(INT_32 p_1)
{
INT_32 i = 0, j = 0;

switch (p_1)
{
case 0:
j = 0;
break;
case 1:
case 2: /* not compliant */
j=i;
break;
default:
i = j + 1;
}

return i + j;
}

26 S:Infinite loop used.避免使用死循环:

1
2
3
for(;;)
while(1) {...}
do .. while(1)

27 S:Void procedure with return statement. 函数返回值被定义为void,却仍然有返回值,此条在VS2008中不能编译通过。

28 S:Duplicated Base Classes in a Derived class. 某个类有两个父类,在两个父类中存在同名函数,当子类调用该函数时会造成混乱:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Base
{
public:
void func(void);
};


class Sub1: public Base { /* ... */ };
class Sub2: public Base { /* ... */ };

/********************************************************
* Standard 28 S : Duplicated Base Classes in a Derived class.
********************************************************/

class derived : public Sub1, public Sub2 { /* ... */ }; // not compliant

void static_028 ( void )
{
derived d;
d.func(); // ambiguous whether Sub1::Base::func()
// or Sub2::Base::func()
}

29 S:Use of += or -= operators found. 避免使用+= 或者 -=运算符。

30 S:Deprecated usage of ++ or – operators found. 避免在表达式中使用连+或-符号:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void static_30(void)
{
INT32_t x = 1u;
INT32_t y = 2u;

BOOL flag = FALSE;

if (flag == FALSE)
{
x++; /* compliant */
}

x = x + y++; /* not compliant */
func( x++ ); /* not compliant */
}

31 S:Use of break statement in loop. 避免在循环中使用break语句,建议用置标识的方法跳出循环。

32 S:Use of continue statement.避免在循环中使用continue语句,建议用置标识的方法控制循环。

33 S:Use of ternary operator found.避免使用三目运算符。

34 S:No parameters declared in proc specification. 在函数声明时无参数,在函数实现时却有参数,在VS2008下编译不通过。

35 S:Static procedure is not called in text analysed. 函数被声明为static类型,却没有在本文件调用,那么static修饰符是不必要的。

36 S:Function has no return statement. 函数不为void类型却无返回值。

37 S:Procedure parameter has a type but no identifier. 避免函数参数有类型却忽略变量名:

1
2
3
4
5
6
void static_37 ( UINT32_t ); /* not compliant */

void static_37 ( UINT32_t ) /* not compliant - constraint error */
{
/*do something*/
}

38 S:Use of static class member. 不建议对类中的变量和函数使用static修饰符。

39 S:Unsuitable type for loop variable. 有些类型不适合当作控制循环的变量,如float类型:

1
2
3
4
5
6
7
8
9
void static_39( void )
{
FLOAT32_t f = 0.0F;

for (f = 0.0F; f < 10.0F; f = f + 1.0F) /* not compliant */
{
/* ... */ ;
}
}

40 S:Loop index is not declared locally. 避免控制循环条件的变量不在本函数内声明,有可能引起循环判断的条件失控:

1
2
3
4
5
6
7
8
9
10
INT32_t loop_standards (INT32_t p_1)
{
INT32_t r = 10;

for (global_f = 0; global_f < 10; global_f = global_f + 1) /* not compliant */
{
r--;
}
return r;
}

41 S ~ 60 S

41 S:Ellipsis used in procedure parameter list. 函数入参中使用省略符号,省略符号允许不确定的入参个数,建议避免该编程方式的使用。

42 S:Use of bit field in structure declaration. 避免在结构体声明中使用位字段

1
struct bitfield1 {INT_32_t  x:1;};  /* not compliant */

43 S:Use of setjmp/longjmp. 避免使用setjmp/longjmp语句,使用该语句使得程序移植性差,结构混乱。

44 S:Use of banned function or variable. 不允许使用关键字命名变量和函数,避免使用与库文件中同名的函数和变量。

45 S:Use of C++ keyword. 不允许使用C++关键字:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void static_45(void)
{
UINT32_t public = 0; /* not compliant */
UINT32_t private = 0; /* not compliant */
UINT32_t protected = 0; /* not compliant */
UINT32_t operator = 0; /* not compliant */
UINT32_t new = 0; /* not compliant */
UINT32_t template = 0; /* not compliant */
UINT32_t virtual = 0; /* not compliant */
UINT32_t delete = 0; /* not compliant */
UINT32_t friend = 0; /* not compliant */
UINT32_t cout = 0; /* not compliant */
UINT32_t cin = 0; /* not compliant */
UINT32_t endl = 0; /* not compliant */
/* ... */
}

46 S:extern not in nominated include file.在某些程序中,只有指定的文件可以使用extern修饰符,如果不在指定的文件中使用extern修饰符静态测试会提示警告。

47 S:Array bound exceeded. 使用数组下标获取数组内容时,需要对越界进行防护。

48 S:No default case in switch statement. 避免在使用switch语句时无default分支:

49 S:Logical conjunctions need brackets. 逻辑运算符连接的判断条件,需要使用括号来包围。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void static_49(void)
{
BOOL flag = TRUE;
INT_32 y = 0, x = 0, z = 1;

if (x < 0 || z + y != 0) /* not compliant */
{
flag = FALSE;
}

if ((x < 0) || (z + y != 0)) /* compliant */
{
flag = FALSE;
}
}

50 S:Use of shift operator on signed type. 避免对有符号数使用移位运算符:

51 S:Shifting value too far. 避免在移位操作中移动跨度过长。

52 S:Unsigned expression negated.对有符号变量进行运算,有造成变量翻转的风险。

53 S:Use of comma operator.避免使用逗号运算符。

54 S:Sizeof operator with side effects. 不能对表达式使用sizeof操作符。

55 S:Expression with more than one function. 避免在一个表达式中使用两个函数的返回值。

56 S:Equality comparison of floating point. 避免对两个浮点型数据进行比较。

57 S:Statement with no side effect. 避免出现即不改变逻辑又不进行赋值的无效语句。

58 S:Null statement found. 在某个控制语句前出现空行代码,这个空行有可能是开发人员忘记了实现某个功能而留下的坑,如果确实想空一行再写代码,建议补充注释:

1
2
3
4
5
6
7
8
9
10
void static_58(void)
{
UINT32_t Timing_Loop = 100U;

/* not compliant - decrement is not part of loop */
while (Timing_Loop > 0U);
Timing_Loop--;

; /* compliant as followed by comment */
}

59 S:Else alternative missing in if. 在与if/else if配对中缺少else的分支:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void static_59 (void)
{
UINT32_t x = 1u;

if ( x == 1u )
{
/* ... */ ;
}
else if ( x == 5u)
{
/* ... */ ;
}
/* not compliant */
}

60 S:Empty switch statement. 避免出现空switch(无case的情况)语句。

61 S ~ 80 S

61 S:Switch contains default only. 避免switch语句只有default分支而没有case分支。

62 S:Switch case not terminated with break. 建议每个case分支都有break语句。

63 S:Empty parameter list to procedure/function. 函数无入参时,建议增加void修饰:

1
2
3
4
void static_63(void) /* compliant */
{
/* ... */
}

64 S:Void procedure used in expression. 函数返回值为void类型,却对返回值进行操作,这在vs2008中是编译失败的。

65 S:Void variable passed as parameter. 避免使用void类型修饰函数入参:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void void_para_func(void P1)
{
/* ... */
}

/******************************************************************
* Standard 65 S : Void variable passed as parameter.
* Does not Compile with VC++
******************************************************************/

void static_65( void )
{
void v_ptr;
UINT32_t a;

void_para_func(v_ptr); /* not compliant */

void_para_func((void)a); /* not compliant */
}

66 S:Function with empty return expression.定义有返回值的函数,却什么也没有返回,这在vs2008中是编译失败的。

1
2
3
4
5
UINT32_t static_66 ( void )
{
/* ... */
return; /* not compliant */
}

67 S:#define used in a block. define语句应当出现在文件开头处,不应当在函数体内使用。

68 S:#undef used. 避免使用#undef语句。

69 S:#pragma used. 避免使用#pragma语句。

70 S:Logical comparison of pointers. 对指针的比较只允许使用(== and !=)

1
2
3
4
5
char * x;
char * y;
....
if (x>y) { /* Incorrect, Unsafe*/ }
if (x==y) { /* Correct usage*/ }

71 S:Pointer assignment to wider scope. 该规则用于检查对象的指针是否被分配给超过其作用域范围的值。 由于局部变量在运算完成后,指针指向的变量空间可能被收回,那么被赋值的外部变量可能指向未知的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
UINT32_t *ptr;
UINT32_t* static_71(void)
{
static UINT32_t w = 10u;
UINT32_t local = 3U;
UINT32_t *local_ptr = &local;

ptr = &local; /* Not Compliant */

ptr = local_ptr; /* Not Compliant */

return &w; /* Not Compliant if modifier is set to 0 */
}

72 S:Signed bit field less than 2 bits wide.有符号型变量有一位表示符号,至少还需要一位表示值。

73 S:Bit field not signed or unsigned int.位字段被定义成其他类型是危险的:

1
2
3
4
struct static_73
{
UCHAR x:1; /* Not Compliant */
};

74 S:Union declared. 避免使用联合定义数据结构。

75 S:Executable code before an included file. #include语句必须出现在可执行语句之前。

76 S:More than one of # or ## in a macro. 不允许宏定义中出现多个 # 或者 ##:

1
2
/* not compliant */
#define SetVariable(Variable, Value) (dummy(NewString##Variable, #Value))

77 S:Macro replacement list needs parentheses. 使用宏定义时,注意使用括号来限定宏运算的边界,避免在宏被替换后出现意想不到的运算组合:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#define increment_NOK(a)    (a) + 1

#define increment_OK(b) ((b) + 1)

/********************************************************
* Standard 77 S : Macro replacement list needs parentheses.
********************************************************/

void static_77(void)
{
INT32_t result = 1;
result = increment_NOK(result) * 2; /* result = 3 */

result = 1;
result = increment_OK(result) * 2; /* result = 4 */
}

78 S:Macro parameter not in brackets. 同77 S:

1
2
#define abs(x) (((x) >= 0) ? (x) : -(x)) /* Compliant */
#define abs(x) x >= 0 ? x : -x /* Not compliant */

79 S:Macro contains unacceptable items. 宏定义中避免出现关键字:

1
2
/* not compliant */
#define t void

80 S:Pointer indirection exceeds 2 levels. 避免使用二级指针。

81 S ~ 100 S

81 S:Use of trigraphs. C语言不允许使用三字母词,编译不能通过:

1
2
3
4
void static_81(void)
??< /* not compliant */
/* ... */
}

82 S:Use of wide string literal. 避免使用宽字符类型:

1
2
3
4
5
6
void static_82(void)
{
wchar_t WideChar = L'1'; /* not compliant */

/* ... */
}

83 S:Octal number found. 由于8进制数以0开头,容易造成混淆,所以在代码中应当避免使用八进制计数:

1
2
3
4
code[1] = 109;   /* set to decimal 109 */
code[2] = 100; /* set to decimal 100 */
code[3] = 052; /* incorrect - set to decimal 42 */
code[4] = 071; /* incorrect - set to decimal 57 */

84 S:Register variable declared. 避免使用Register关键字修饰变量:

1
2
3
4
5
6
void static_84(void)
{
register SINT_32 ri = 0; /* not compliant */

/* ... */
}

85 S:Incomplete initialisation of enumerator. 初始化枚举类型时候,或者全部默认,或者全部初始化,或者只初始化第一个值,其他的初始化方式是不妥的:

1
2
3
4
enum VAL {x, y, z};              /*GOOD - no explicit initialisation*/
enum VAL {x = 1, y, z}; /*GOOD - first value only*/
enum VAL {x = 2, y = 3, z = 4}; /*GOOD - all values set*/
enum VAL {x, y, z = 1}; /*BAD*/

86 S:Attempt to define reserved word.避免define保留字段。

87 S:Use of pointer arithmetic. 避免对指针使用数学运算:

1
2
3
4
5
6
7
8
9
void static_87(void)
{
UINT32_t w;
UINT32_t array[5];
UINT32_t * p1_ptr;

p1_ptr = array;
w = *(p1_ptr + 8); /* not compliant */
}

88 S:Procedure is not pure assembler. 避免C语言与汇编语言混合使用。

89 S:char type not signed or unsigned. char类型建议定义为signed或者unsigned类型。

90 S:Basic type declaration used. 对于不同编译器基础类型的宽度可能不同,该建议在程序编写前做如下定义:

1
2
3
4
5
6
7
8
9
10
typedef char                            CHAR_t;
typedef unsigned char UCHAR_t;
typedef unsigned short UINT16_t;
typedef unsigned int UINT32_t;
typedef signed char SCHAR_t;
typedef signed short SINT16_t;
typedef signed int SINT_32_t;
typedef float FLOAT_32_t;
typedef double FLOAT_64_t;
typedef enum {FALSE = 0, TRUE = 1} BOOL_t;

91 S:Name redeclared in another C name space (MR). 尽管C语言允许在不同的作用域定义相同的变量名,为避免混淆建议定义不重名变量(在复杂系统中该条很难实现)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct s_91
{
UINT32_t s_91; /* not compliant */
UINT32_t u_1;
};


UINT32_t static_91 (void)
{
UINT32_t var_1;

static_91: /* not compliant */
var_1 = 1;
return (var_1);
}

92 S:Duplicate use of a name in an enumeration.针对枚举类型,建议不使变量重名:

1
2
3
4
5
6
7
void static_92 (void)
{
enum Name_type { e1, duplicate } EnumVar;

EnumVar = e1;
/* ... */
}

93 S:Value is not of appropriate type.强制要求类型检查,不同类型之间转换需要显示转换:

1
2
3
4
5
6
7
8
void STATIC_93(void)
{
FLOAT_32 fl;

fl = 2.0; /* not compliant - Requires explicit assignment of 2.0F */

/* ... */
}

94 S:Casting operation on a pointer. 避免对指针进行强制类型转换(通过修改测试软件配置,可以允许指针在同类型之间转换):

1
2
3
4
5
6
static void static_94(UINT_32 * p1_ptr)
{
FLOAT_32 v_1;

v_1 = (FLOAT_32) p1_ptr;
}

95 S:Casting operation to a pointer. 给指针赋值安全的方式是通过获取对象地址,强转赋值的方式有风险:

1
2
3
4
5
6
7
struct Astruct { UINT_32 a; };

void static_95(UINT_32 *intptr)
{
struct Astruct *Astructptr;
Astructptr = (struct Astruct *) intptr; /* not compliant */
}

96 S:Use of mixed mode arithmetic. 不同类型的变量进行数学运算,需要进行强制转换:

1
2
3
4
5
6
7
8
9
static void static_96(void)
{
INT32_t i32 = 10;
FLOAT64_t f64 = 20.5;
FLOAT32_t f32 = 2.0F;

f64 = i32 + f64; /* not compliant */
f64 = f64 * f32; /* compliant */
}

97 S:Use of redundant cast. 避免使用不必要的强制类型转换:

1
2
3
4
5
6
void static_97(void)
{
SINT32_t sx,sy = -10;

sx = (SINT32_t) sy + 1; /* not compliant */
}

98 S:Actual and formal parameters inconsistent (MR).函数调用时传入的参数类型与定义时不一致。

99 S:Function use is not a call.函数缺少声明。

100 S:#include filename is non conformant. include语句中禁止使用 字符’ \ /*。

1
#include <\ctype.h> /* not compliant */

101 S ~ 120 S

101 S:Function return type inconsistent. 函数的实际返回值类型与定义的返回值类型不同:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
UINT32_t static_101( UINT32_t par_1)
{
switch (par_1)
{
case 0:
return (-1); /* not compliant */
break;
case 1:
return (1U);
break;
case 2:
return (1L); /* not compliant */
break;
case 3:
return (1.0f); /* not compliant */
break;
default:
break;
}
}

102 S:Function and prototype return inconsistent (MR). 函数声明时的返回值类型与实际使用时的返回值类型不同:

1
2
3
4
5
6
7
8
9
10
11
12
UINT32_t static_102(UINT32_t p_1, UINT16_t p_2);

/**************************************************************
* Standard 102 S : Function and prototype return inconsistent.
**************************************************************/

SINT32_t static_102(UINT32_t p_1, UINT16_t p_2) /* not compliant */
{
SINT32_t result = 0;
/* ... */
return result;
}

103 S:Function and prototype param inconsistent (MR). 函数声明时的参数类型与实际使用时的参数类型不同:

1
2
3
4
5
6
7
8
9
10
11
BOOL static_103(FLOAT32_t up_1);

/***************************************************************
* Standard 103 S : Function and prototype param inconsistent.
***************************************************************/
BOOL static_103(UINT32_t up_1)
{
BOOL ret = FALSE;
/* ... */
return ret;
}

104 S:Struct field initialisation incorrect. 结构体初始化赋值的类型与定义的类型不符:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct s_type_a
{
SINT32_t xs;
FLOAT32_t fs;
};

/********************************************************
* Standard 104 S : Struct field initialisation incorrect.
********************************************************/

void static_104(void)
{
struct s_type_a sta = {3.14F, 0.0f}; /* not compliant */
/* ... */
}

105 S:Initialisation brace { } fault. 初始化结构体忘记使用大括号会出错:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct pixel
{
UINT32_t colour;
struct {
UINT32_t x, y;
} coords;
};

/***********************************************************
* Standard 105 S : Struct field initialisation brace fault.
***********************************************************/

void static_105(void)
{
UINT32_t xs = 0;
UINT32_t ys = 0;

struct pixel spot = {1u, xs, ys }; /* not compliant */

/* ... */
}

106 S:Volatile declaration.避免使用Volatile修饰变量,Volatile可以在应用程序外被改变,容易造成逻辑混淆。

1
2
3
4
5
6
7
8
void static_106(void)
{
volatile UINT32_t v = 1U; /* not compliant */
UINT32_t x = 0;

x = v;
/* ... */
}

107 S:Type mismatch in ternary expression. 使用三目运算符时类型不匹配:

1
2
3
4
5
6
7
static void static_107( BOOL flag )
{
UINT32_t x = 0U;
FLOAT32_t f = 0.0F;

x = (flag ? f : x);
}

108 S:Assignment types do not match. 变量赋值时类型不匹配:

1
2
3
4
5
6
7
void static_108(void)
{
FLOAT32_t fl = 2.0F;
FLOAT_64 dbl = 3.0;

fl = dbl; /* not compliant */
}

109 S:Array subscript is not integral. 数组的索引必须为正数。

110 S:Use of single line comment //. 由于使用双斜杠标记注释的做法不是对所用的编译器通用,建议对注释段使用/**/的方式。

111 S:Label is not part of switch statement . 只有在switch语句中使用标签语法是安全的。

112 S:Typedef name redeclared.使用typedef 时某个名称被重复使用是危险的:

1
2
3
4
5
6
7
8
9
10
11
12
typedef SINT32_t mytype;

/*******************************************
* Standard 112 S : Typedef name redeclared.
********************************************/

void static_112(void)
{
typedef FLOAT32_t mytype; /* not compliant */

/* ... */
}

113 S:Non standard character in source.源文件中出现非法字符,合法的字符如下:

1
2
3
4
3***** The lines of permissible characters,(80A1),those NOT changed
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
()[].!~+-*/%<>=& ^|?:;,0123456789_{}'"#\$@<space><tab>

114 S:Expression is not Boolean. 表达式类型不为BOOl类型,或者表达式的运算对象都为BOOL类型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void static_114(BOOL bl, UINT32_t a)
{
UINT32_t x;
BOOL flag;

flag = bl + bl; /* not compliant */

if (a) /* not compliant */
{
; /* ... */
}
if (a == 1) /*compliant */
{
; /* ... */
}

x = ( a && bl ? 1U : 0U ); /* not compliant */
}

115 S:String incorrectly terminated. string类型换行时需要使用反斜杠,否则在某些编译器中造成string类型结尾异常的错误:

1
2
3
4
5
6
7
8
9
10
11
/*******************************************************
* Standard 115 S : String incorrectly terminated.
*******************************************************/
void static_115(void)
{
CHAR* str1 = "string\
literal"; /* compliant */

CHAR* str2 = "string
literal"; /* not compliant */
}

116 S:Boolean comparison with 0 preferred. 与一个已知值的变量进行比较时,使用不等号来判断FALSE比使用等号判断TRUE安全:

1
2
3
4
5
6
7
8
9
10
11
12
13
void static_116 (void)
{
UINT32_t x = 2u;

if ( x == 1u ) /* not compliant */
{
/* ... */ ;
}
if ( x != 1u )
{
/* ... */ ;
}
}

117 S:Logical negation of constant value. 对const变量取反是危险的:

1
2
3
4
5
6
7
8
9
void static_117(void)
{
BOOL flag = FALSE;

if (flag == (BOOL)!1) /* not compliant */
{
/* ... */
}
}

118 S:main must be int (void) or int (int,char* []).C语言Main函数的格式必须是int (void) 或者 int (int,char* [])。

119 S:Nested comment found.避免在注释中出现子注释:

1
2
3
4
5
6
void static_119(void)
{
/* This is the Outer Comment
/* This is the Inner Comment - not compliant
*/
}

120 S:Use of bit operator on signed type. 避免对有符号类型进行位运算:

1
2
3
4
5
6
7
8
void static_120(void)
{
SINT32_t b = 1;

b = b | 1; /* not compliant */

/* ... */
}

121 S ~ 140 S

121 S:Use of boolean expression in switch. 避免在switch case语句中使用BOOL类型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void static_121(void)
{
BOOL flag = FALSE;

switch (flag) /* not compliant */
{
case TRUE:
break;
case FALSE:
break;
default:
break;
}
}

122 S:Use of abort, exit, etc. 避免使用语法abort, exit, etc:

1
2
3
4
5
6
7
8
9
10
11
/********************************************************
* Standard 122 S : Use of abort, exit, etc.
********************************************************/
void static_122(BOOL flag)
{
if (flag)
{
abort();
}
exit(0);
}

123 S:Use of underlying enum representation value. 枚举类型只允许在同类型之间比较:

1
2
3
4
5
6
7
8
9
10
void static_123(void)
{
enum E_type { Enum1, Enum2 , Enum3};

UINT32_t ui;

ui = Enum1; /* not compliant */

/* ... */
}

124 S:Use of prefix ++ or –. 尽量少使用自增或自减运算符。

125 S:Use of ## or # in a macro. 为避免意外的结果发生,不要在宏定义中使用##或#。

126 S:A #if has no #endif in the same file.#if和#endif需要成套使用。

127 S:Array has no bounds specified. 数组声明时候信息需要完整:

1
2
3
4
5
6
void static_127( INT32_t par[] ) /* not compliant, unless modifier 286 set */
{
INT32_t array[] = {0, 1, 2}; /* not compliant, unless MISRA-C:2004 used */

/* ... */
}

128 S:Parameter has same name as global variable. 函数参数名避免与全局变量重名。

129 S:Parameter has same name as type or tag. 函数参数名避免与结构体重名。

130 S:Included file is not permitted. 某些头文件在测试工具中规定不允许使用。

131 S:Name reused in inner scope. 避免内部变量与外部变量重名。

132 S:Assignment operator in boolean expression.bool表达式中避免出现变量赋值语句:

1
2
3
4
5
6
7
8
9
void static_132(void)
{
BOOL flag = FALSE;

if (flag = FALSE) /* not compliant - should be (flag == FALSE) */
{
/* ... */
}
}

133 S:Assignment operator in RHS of && or ||.运算符两侧避免出现赋值语句:

1
2
3
4
5
6
7
8
9
10
void static_133(void)
{
BOOL flag = FALSE;
INT32_t y = 0, x = 0;

if (flag && ((x = y) == 0)) /* not compliant */
{
/* ... */
}
}

134 S:Volatile variable in complex expression. 避免使用Volatile修饰变量,更不要在复杂表达式中使用Volatile变量。

135 S:Parameter list is KR. 某些编译器支持函数参数声明时只声明名称而不定义类型,在使用时再定义类型,应当避免这种老式用法:

1
2
3
4
5
6
void static_135(p_1,  p_2) /* not compliant */
UINT32_t p_1;
UINT32_t p_2;
{
/* ... */
}

136 S:Bit operator with boolean operand. bool表达式中避免使用位操作符,因为位操作符(|或者&)容易与连接符(||或者&&)混淆。

137 S:Bit operator acting on boolean value. 同136S

138 S:Anonymous bit field used in structure.避免在结构体位域中使用匿名方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
struct bad
{
UINT32_t x : 1;
UINT32_t : 1;
UINT32_t z : 1;
}

struct good
{
UINT32_t x : 1;
UINT32_t y : 1;
UINT32_t z : 1;
}

139 S:Construct leads to infeasible code.指在代码中某个逻辑导致部分语句不可达,例如两个常量的比较,结果是恒真或假的,又比如两个并列的条件是耦合的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
typedef enum
{
LANE_0 = 0,
LANE_1 = 1,
LANE_LAST = 3
} lane_t;

extern lane_t get_lane (void);

/********************************************************
* Standard 139 S : Construct leads to infeasible code.
********************************************************/

void static_139(void)
{
lane_t lane = get_lane();
if ((lane > LANE_0) && (lane <= LANE_LAST))
/* not compliant - False branch of 'lane <= LANE_LAST' never reached */
{ /* ... */ }

if (defval)
/* not compliant - True branch never reached*/
{ /* ... */ }

if (0) { /* NEVER EXECUTED */ } else {...};
}

140 S:Infeasible loop condition found. 避免在循环中出现恒真或恒假的条件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#define defval 0

/********************************************************
* Standard 140 S : Infeasible loop condition found.
********************************************************/

void static_140(void)
{
while (0) /* not compliant */
{ /* ... */ }

while(defval) /* not compliant */
{ /* ... */ }
}

141 S ~ 160 S

141 S:Incomplete structure or class declaration. 结构体或者类声明不完整:

1
2
3
4
5
6
struct atagname; /* not compliant */
struct atagname
{
UINT32_t A;
UINT32_t B;
}; /*compliant */

142 S:Parameter list declarations are inconsistent. 函数某些参数缺少类型或者名称:

1
2
3
4
void static_142(UINT32_t , UINT16_t p_2)  /* not compliant */
{
/* ... */
}

143 S:Curly brackets used in expression. 表达式中使用大括号会对某些编译器造成干扰,应当避免使用:

1
2
3
4
5
6
UINT32_t static_143(UINT32_t p_1)
{
UINT32_t result;
result = p_1{}; /* not compliant */
return result;
}

144 S:Floating point not permitted. 避免使用浮点类型,尤其是对浮点类型的操作,应为对浮点类型的操作可能使精度降低:

1
2
3
4
5
6
FLOAT32_t static_144(FLOAT32_t p_1,FLOAT32_t p_2)  /* not compliant */
{
FLOAT32_t result; /* not compliant */
result = p_1 + p_2;
return result;
}

145 S:#if has invalid expression. #if语句后应当为BOOL类型,如下的表达式写法对有些编译器会造成误解:

1
#if MACRO_NAME JUNK_NAME

146 S:#define with empty parameter list.注意使用#define定义表达式,参数为空的情况,如下给出了建议的写法:

1
2
#define Macro() some_macro_body /* not compliant */
#define Macro some_macro_body /* compliant */

147 S:Spurious CHAR_tacters after preprocessor directive. 避免出现不必要的字符,注意下面情况中结尾的分号是不必要的:

1
2
3
4
5
#ifdef STATIC_147

typedef unsigned CHAR_t UCHAR_t;

#endif ; /* not compliant */

148 S:No return type for function/procedure. 函数缺少返回类型,vs2008下编译失败:

1
2
3
4
5
6
static_148(UINT32_t p1);  /* not compliant */

static_148(UINT32_t p1) /* not compliant */
{
/* ... */
}

149 S:Reference parameter to procedure is reassigned. 传入函数的引用参数在函数内被重新赋值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
CHAR_t *static_149(CHAR_t *p1);

void test_149(void)
{
CHAR_t *a = "Query";
CHAR_t *b;
b = static_149(a);
}

/********************************************************
* Standard 149 S : Reference parameter to procedure is reassigned.
********************************************************/
CHAR_t *static_149(CHAR_t *p1)
{
static CHAR_t *newA = "Response";

p1++; /* not compliant */
p1 = p1+1; /* not compliant */
p1 = newA; /* not compliant */

return p1;
}

150 S:Volatile or const used in function type. 对函数的返回值使用Volatile 或者 const修饰是无意义的:

1
2
3
4
5
6
7
8
9
10
11
12
volatile UINT32_t STATIC_150(void);  /* not compliant */

/***********************************************************
* Standard 150 S : Volatile or const used in function type.
***********************************************************/

volatile UINT32_t STATIC_150(void) /* not compliant */
{
volatile UINT32_t r;
/* ... */
return r;
}

151 S:Use of global variable in macro definition. 避免在宏定义中使用全局变量:

1
2
3
UINT32_t globvar;

#define STATIC_151 globvar /* not compliant */

152 S:Use of a comment in a macro definition.宏定义语句中不建议增加注释,注释内容可以写在语句上一行:

1
#define STATIC_152 3 /* not compliant comment */

153 S:Use of a comment in a pre-processor directive.同147S,在编译器不解析的地方不建议出现注释行:

1
2
3
#ifdef STATIC_153 /* A Comment  - not compliant */
/* ... */
#endif /* Another Comment - not compliant */

154 S:Nested header files found. 避免嵌套包含头文件,需要的头文件建议直接包含:

1
2
3
4
5
6
7
8
Static_154_1.h
#include "c_standards.h"

Static_154.h
#include "Static_154_1.h"

Static_154.c
#include "Static_154.h" /* not compliant,proposal to included c_standards.h directly*/

155 S:Comments between preprocessor directives. 避免用#ifdef语句来写注释,防止#ifdef语句中的变量被定义后,注释被编译报错:

1
2
3
#ifdef STATIC_155
this acts as a comment, as STATIC_155 is undefined.
#endif

156 S:Use of ‘defined’ keyword in macro body. 宏定义中避免使用’defined’关键字:

1
#define STATIC_156(x) defined(x)  /* not compliant */

157 S:Modification of string literal. string类型存储在内存的只读块,改变string类型的字符是危险的:

1
2
3
4
5
6
7
void static_157(void)
{
CHAR_t *c = "1234567890";

c[7] = '0'; /* not compliant */
*(c+6) = '1'; /* not compliant */
}

158 S:Expression with more than N subconditions.并列条件超过N时报警,N值是可配置的:

1
2
3
4
5
6
7
8
9
10
11
12
13
void static_158(void)
{
INT32_t a1,b1,c1,d1,e1;
INT32_t a2,b2,c2,d2,e2;
INT32_t a3,b3,c3,d3,e3;

if ((a1==0) && (b1==0) && (c1==0) && (d1==0) && (e1==0)
&& (a2==0) && (b2==0) && (c2==0) && (d2==0) && (e2==0)
&& (a3==0) && (b3==0) && (c3==0) && (d3==0) && (e3==0)) /* not compliant */
{
/* ... */
}
}

159 S:Comparing pointer with zero or NULL.指针与NULL比较时,建议对NULL进行类型转换与指针类型一致:

1
2
3
CHAR_t *message;
if (message != (CHAR_t *)(NULL)) /* compliant */
if (message != NULL ) /* not compliant */

160 S:Loop in macro expansion. 避免在宏定义中出现循环,下面的写法除了增加代码行数外是无意义的:

1
2
3
4
5
6
#define A B
#define B A

#define C D
#define D E
#define E C

161 S ~ 180 S

161 S:Declaration in for statement. 避免在for循环中定义变量:

1
2
3
4
5
6
7
8
9
void STATIC_161(void)
{
UINT32_t x, y=0;

for(unsigned x(0);x <3;x++) /* not compliant */
{
y++;
}
}

162 S:Method defined within class declaration. 除了成员函数,不要在类申明中定义函数。

163 S:Function starts with upper case character. 建议与175S一起取消。

164 S:Use of void * pointer. 避免使用void类型指针:

1
2
3
4
5
6
7
8
9
10
11
12
static void proc(void *ptr) { ; } /* not compliant */

void *a_proc (void) /* not compliant */
{
return NULL;
}

void static_164 (void)
{
void * p = a_proc(); /* not compliant */
proc(p);
}

165 S:Nested class declaration. 避免嵌套使用类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class one {

public:
long along;
class nested
{
public:
short s;
nested(){;}
};
one()
{
nested anest;
}
};

166 S:Class declared in function body.避免在函数体内定义类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class one {

public:
long l;
one(){;}
void aproc()
{
class inproc1
{
public:
short s;
inproc1(){;}
};
}
};

167 S:Class variable declared in class definition. 建议不要直接在结构体或者类定义后申明变量,使用typedef是更好的做法:

1
2
3
4
5
6
class one {
public:
long a;
one(){;}

} aone, *paone;

168 S:Call by value parameter not const. 值类型的函数参数传递建议使用const修饰:

1
2
3
4
5
6
7
8
9
10
static void aproc(SINT32_t iv_param) {;}        /* not compliant */
static void bproc(const SINT32_t ic_param) {;}

static SINT32_t static_168 (void)
{
SINT32_t loc_var = 0;

aproc(loc_var);
bproc(loc_var);
}

169 S:Use of forward reference of class member. 注意在类中变量的定义要在使用之前:

1
2
3
4
5
6
7
8
9
10
11
12
13
class ok
{
public:
INT32_t x;
ok(void) { x = 1; }
};

class notok
{
public:
notok() { d = 91; /* not compliant */ }
INT32_t d;
};

170 S:Procedure call has no prototype and no defn. 被调用的函数缺少申明或者定义。

171 S:已取消

172 S:Variable declared multiply.变量重复定义:

1
2
3
4
5
6
7
8
9
10
UCHAR_t ddd;

UCHAR_t ddd; /* not compliant */

UCHAR_t ddd = 0U;

static void static_172(void)
{
;
}

173 S:Class member starts with upper case character.类的函数应当以小写字符开头命名(构造函数除外):

1
2
3
4
class one {
public:
void Upper2_out(); /* not compliant */
};

174 S:Class member starts with lower case character.类的成员函数应当以大写字符开头命名:

1
2
3
4
5
6
7
8
class one {
public:
INT32_t x;

void notokproc1 () /* not compliant */
{
}
};

175 S:Function starts with lower case character. 建议与163S一起取消。

176 S:Non standard escape sequence in source. 避免出现转义字符:

1
2
3
4
5
6
7
8
9
10
11
12
13
void static_176(void)
{
char c = 'b';

switch(c)
{
case '\m': /* not compliant */
break;

default:
break;
}
}

177 S:Identifier not declared on new line. 建议每个变量都单起一行定义:

1
2
3
4
5
6
7
INT32_t okvar, notok2; /* not compliant */

void static_177(void)
{
okvar = 0;
notok2 = 2;
}

178 S:Declaration statement not on new line.同177S:

1
2
3
4
5
6
7
8
9
10
11
INT32_t * oka;
INT32_t b; INT32_t *notoka; /* not compliant */

void proc(INT32_t * s, INT32_t *ok); /* compliant */

struct tag0 {INT32_t * w; INT32_t *notokq;} astr; /* not compliant */

static void static_178(void)
{
oka = 0;
}

179 S:Extern not at start of header file. extern类型变量应当声明在源文件开头处:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "c_standards.h"
#include "Static_179.h"

/********************************************************
* Standard 179 S : Extern not at start of header file.
********************************************************/

static void static_179(void)
{
;
}

/*
* Copyright (c) 2001 Liverpool Data Research Associates
*
*
*/
Static_179.h
INT32_t var;

extern INT32_t ex; /* not compliant */

180 S:No space between * or & and name in declaration. * 或者 & 与变量名之间应当有空格。

181 S ~ 200 S

181 S:No space between if, while, for and expresn. (if, switch, while, for)关键字后请跟上一个空格:

1
2
3
4
5
6
7
8
9
10
11
12
INT_t32_t main(void)
{
INT_t32_t i=3;
if( 1==2 ) {2;} /* not compliant */
switch(i){ /* not compliant */
}
switch (i){
}
while(i==0){2;} /* not compliant */
do{2;}while(i==0); /* not compliant */
for(i=0;i>2;i++){2;} /* not compliant */
}

182 S:No space after semi colon in for expression. for循环表达式中分号后打一个空格,看上去更整洁:

1
for ( i = 0; i < 5; i++ ){ i++;}    /*compliant */

183 S:No newline after semi colon. 分号后再起一行,便于阅读:

1
2
3
4
5
6
7
static void static_183(void)
{
INT_t32_t i; INT_t32_t j; /* not compliant */

for (i = 0; i < 5; i++)
{i++;} /* not compliant */
}

184 S:Spaces round -> or [] operators. -> 或 [] 操作符连接处不能有空格:

1
2
3
4
5
void static_184(struct tag * astr,
INT_t32_t b [] /* not compliant */ )
{
astr ->f = 2; /* not compliant */
}

185 S:Space between unary operator and operand. 单目运算符和操作对象之间不应当有空格:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void proc(INT_t * g)
{
* g = 77; /* not compliant */
*g = * g + 77; /* not compliant */
}

INT_t main(void)
{
INT_t i = 9;
INT_t j = 19;
INT_t * p; /* not compliant */

i = - j; /* not compliant */
p = & j; /* not compliant */
}

186 S:Space missing before or after binary operator.二目运算符之间缺少空格:

1
2
3
4
5
6
7
8
9
10
11
12
INT_t main(void){
INT_t i = 9;
INT_t j =8; /* not compliant */
INT_t k= 7; /* not compliant */
UINT_t x = 3;
UINT_t y = 17;

i= j; /* not compliant */
i = j /k; /* not compliant */
i = j <<k; /* not compliant */
i = j && k;
}

187 S:Tab CHAR_tacter in source. 源文件中使用空格而不是Tab键缩进。

188 S:{ or } not on line by itself. 为了提高可读性,花括号的使用需要注意:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct tagnotok { CHAR_t a; } data; /* not compliant */

struct
{
CHAR_t x;
} moredata;

void proc_ok()
{
;
}

void static_188(void) { /* not compliant */
;
}

189 S:Input line exceeds limit. 每一行的字符数不能过多。

190 S:{ … } contents not indented by N spaces. 花括号后一行缩进N个空格,N值可以配置。

191 S:Space between function name and parenthesis. 函数名和括号之间不应当有空格:

1
2
3
void notokproc1 () /* not compliant */
{
}

192 S:Static not on separate line in function defn.为了提高代码可读性,inline, static 和 const修饰的函数,修饰符和参数可以分两行写。

193 S:Inline not on separate line in function defn.同192S,内连函数定义中修饰符和函数定义可以分两行写:

1
inline void one::mem1(void) /* not compliant */

194 S:Const not on separate line in member defn.同192S,const修饰符和函数定义可以分两行写。

195 S:Function return type needs a new line. 为了提高代码可读性,函数定义中返回值类型和参数可以分两行写。

196 S:Access specifier missing (added by Testbed). 类定义中成员缺少Public、Protected或Private修饰符。

197 S:Access specifiers in invalid order. 访问权限修饰符在类定义时应当遵循特定的顺序,首先是Public类型,然后是Protected类型,最后是Private类型:

1
2
3
4
5
6
7
8
class class_197 {
public:
INT_t_16 d;
private: /* not compliant */
INT_t32_t a;
protected: /* not compliant */
INT_t32_t q;
};

198 S:Use of privacy statement in struct.结构体中成员不应当修饰为privacy类型。

199 S:Use of anonymous namespace. 避免使用匿名命名空间。

200 S:Define used for numeric constant. C++中建议const代替宏定义常量,C中建议使用宏代替const定义常量。

201 S ~ 220 S

201 S:Use of numeric literal in expression. 该条规则建议使用宏或者枚举代替具体的数字,以提高代码的可维护性。

202 S:Class data is not explicitly private. 建议类中的成员变量为私有。

203 S:Cast on a constant value. 避免对常量进行强制类型转换:

1
2
3
4
5
6
7
8
9
10
const INT16_t con = 19;
const INT16_t * pcon;

static void static_203(void)
{
INT16_t x;
INT16_t *p;
x = (INT16_t)con; /* not compliant if modifier = 0 */
p = (INT16_t *)pcon; /* not compliant */
}

204 S:continue or goto not defined to rubbish. 避免使用goto和continue语句。

205 S:Use of multiple inheritance. 避免在类中使用复杂的多重继承。

206 S:Class initialiser out of order.类成员初始化的顺序需要与申明时候的顺序一致。

207 S:Use of old style /* comments in C++. 建议C++注释中使用双斜杠。

208 S:Private data name needs trailing underscore. 类的私有变量建议以下划线结尾以做区分:

1
2
3
4
5
6
7
8
class MyClass
{
private:
UINT32_t m_ok_item_;
UINT32_t m_not_ok_item; /* not compliant */
protected:
public:
};

209 S:Preprocessor command indented. 宏定义顶头写,不建议有缩进:

1
2
3
4
#ifndef XXX
/* not compliant */
#define XXX
#endif

210 S:Macro name is not upper case. 建议宏定义变量名大写。

211 S:Overloaded &&, || or comma. 请不要重定义&&, || 或者 comma。

212 S:Use of friend function in class.谨慎的使用友元类,以免在类继承或者重新设计接口是带来隐患。

213 S:Use of friend class.同212S。

214 S:Member not declared virtual.建议基类中函数申明为virtual类型。

215 S:Struct or class called by value. 避免直接使用结构体作为函数的入参,或者作为函数的返回值,这样会消耗额外的内存空间,使用指针是更合理的方式。

216 S:Pointer name does not have required suffix. 建议变量的名称以变量的类型为后缀,增加代码的可读性:

1
2
3
4
5
6
7
8
static void static_216(void)
{
UCHAR_t * pointer; /* not compliant */
UCHAR_t * ptr; /* ok as allowed suffix is ptr */
UCHAR_t * aptr; /* ok as allowed suffix is ptr */

/***/
}

217 S:Names only differ by case. 避免出现两个变量仅仅是某些字符大小写不同:

1
2
3
4
5
6
7
8
9
10
INT32_t Foobar;
INT32_t foobar; /* not compliant */
INT32_t fOobar; /* not compliant */

void aproc(CHAR_t aC2; INT32_t FooBar) {;} /* not compliant */

void static_217(void)
{
struct tag{ CHAR_t aC1, INT32_t FooBar;} local; /* Ok as different scope */
}

218 S:Name is used in standard libraries.命名时避免与C/C++标准库中的名称重复。

219 S:User name starts with underscore. 避免以下划线开始命名变量。

220 S:No prefix for global type. 建议全局变量名称后缀该变量的类型以增加可读性。

221 S ~ 241 S

221 S:Start of class/struct/union/enum lower case. 建议结构体和联合体命名以大写字符开头。

222 S:Start of variable is upper case. 建议变量名以小写字符开头。

223 S:No prefix for global function. 作用域为全局的函数名建议以_func结尾以增加代码的可读性。

224 S:Start of enumeration is upper case. 建议常量和枚举类型的变量以小写字符开头。

225 S:Inappropriate file extension. C的源文件类型为.c,C++源文件类型为.cpp。

226 S:Bit field is not octal, hex or suffix u.位字段建议是八进制、十进制或无符号型:

1
2
3
4
5
6
7
8
9
10
11
12
13
enum {
won = 1,
too = 2
};

struct tag
{
UINT dec : 2; /* not compliant */
UINT oct : 02;
UINT hex : 0x3;
UINT enumr : won; /* not compliant */
UINT decu : 3u;
};

227 S:Numeric bit operand is not octal,hex or u. 位操作建议是八进制、十进制或无符号型:

1
2
3
4
5
6
7
8
void static_227(void)
{
UINT x = 1, y;
y = x & 20; /* not compliant */
y = x & 20u;
y = x & 020;
y = x & 0x20;
}

228 S:Bracket mismatch ( or { in macro definition. 宏定义中缺少( 或者{:

1
2
3
/* Missing right parenthesis (!) in this macro definition of a 'common' symbolic constant */

#define COMMON_SYM_CONSTANT ((2U * 3U) + 2U

229 S:Bracket mismatch ) or } in macro definition. 宏定义中缺少) 或者 }:

1
2
3
/* Missing left parenthesis (!) in this macro definition of a 'common' symbolic constant */

#define COMMON_SYM_CONSTANT 2U * 3U + 2U)

230 S:No copy constructor defined for class. 尽管有默认的构造函数,建议自己实现类的构造函数。

231 S:No assignment operator defined for class. 同230S,建议自己实现构造函数并对变量初始化。

232 S:No destructor defined for class.同230S,建议自己实现析构函数。

233 S:No copy constructor for class with pointers.同230S,建议自己实现拷贝构造函数。

234 S:No assignment operator for class with pointers.同231S。

235 S:No destructor for class with pointers. 同232S。

236 S:New used in class without assignment op. 类中使用new分配空间时,建议定义拷贝赋值运算符:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Person
{
public:
Person();
explicit Person(const UINT_32 personNum);
explicit Person(const Person &person);
~Person();
protected:
private:
UINT_32 personalNumber;
UINT_32 *skillsList;
};

Person::Person(const UINT_32 personNum)
{
personalNumber = personNum;
skillsList = new UINT_32[10]; /* not compliant */
}


static void static_236(void)
{
Person p1(10);
Person q1(10);
q1 = p1; /* invokes (compiler provided) copy assignment constructor */
}

237 S:Assignment operator parameter not const. 拷贝赋值运算符被用来将一个对象中的值拷贝到同类型的另一个对象中,该对象应当为const类型,不被改变:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Person
{
public:
Person();
explicit Person(const Uint_32 personNum);
explicit Person(const Person &person);
Person & operator=(Person &person); // should be a const parameter
~Person();
protected:
private:
Uint_32 personalNumber;
};

Person &Person::operator=(Person &person)
{
if (this != &person)
{
// Assignment code
}
return *this;
}

void foo(void)
{
Person p1(10);
Person q1(10);
q1 = p1;
}

238 S:Number of templates exceeds N.建议减少使用模版:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
template < class T >
class tplate1
{
public:
tplate1();
protected:
private:
Uint_32 value1;
};

template < class T >
class tplate2
{
public:
tplate2();
protected:
private:
Uint_32 value2;
};

template < class T >
class tplate3
{
public:
tplate3();
protected:
private:
Uint_32 value3;
};

template < class T >
class tplate4
{
public:
tplate4();
protected:
private:
Uint_32 value4;
};

template < class T >
class tplate5
{
public:
tplate5();
protected:
private:
Uint_32 value5;
};

template < class T >
class tplate6
{
public:
tplate6();
protected:
private:
Uint_32 value6;
};

template < class T >
class tplate7 // This declaration causes a violation when
{ // limit configured to 6.
public:
tplate7();
protected:
private:
Uint_32 value7;
};


void foo(void)
{
// ...
}

239 S:New used in class without copy constructor. 如果类中使用new分配空间,同时建议定义拷贝构造函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Person
{
public:
Person();
explicit Person(const UINT_32 personNum);
Person & operator=(const Person &person);
~Person();
protected:
private:
UINT_32 personalNumber;
UINT_32 *skillsList;
};

Person::Person(const UINT_32 personNum)
{
personalNumber = personNum;
skillsList = new UINT_32[10]; /* not compliant */
}

static void static_239(void)
{
Person p1(10);
Person q1(p1); /* invokes (compiler provided) copy constructor */
}

240 S:Use of dynamic_cast. 建议减少使用动态类型分配:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Base
{
public:
Base();
explicit Base(const Base &base);
Base& operator=(const Base &base);
virtual ~Base();
protected:
private:
};

class Derived : public Base
{
public:
Derived();
explicit Derived(const Derived &derived);
Derived& operator=(const Derived &derived);
virtual ~Derived();
protected:
private:
};

class DifferentDerived : public Base
{
public:
DifferentDerived();
explicit DifferentDerived(const DifferentDerived &dderived);
DifferentDerived& operator=(const DifferentDerived &dderived);
virtual ~DifferentDerived();
protected:
private:
};

static void static_240(void)
{
Derived *d1 = new Derived;
DifferentDerived *dd1 = dynamic_cast <DifferentDerived *> (d1); /* not compliant */
}

241 S:Start of class/struct/union/enum lower case. 建议结构体和联合体命名以大写字符开头。

评论