logo资料库

RuleChecker 编码规范.doc

第1页 / 共20页
第2页 / 共20页
第3页 / 共20页
第4页 / 共20页
第5页 / 共20页
第6页 / 共20页
第7页 / 共20页
第8页 / 共20页
资料共20页,剩余部分请下载后查看
C++ RuleChecker Rules 有关 C++的 89 个规则,其中有 35 个规则允许根据实际情况配置如何使用(方法是调整 规则提供的参数),其余 54 个规则不允许配置(理由是:业界认可的通行规则或者专家规则)。 这 89 个规则,实际使用中,可以选择其任意子集。 其中,前 70 条规则,是从多家公司收集的编程规则集,提取的精华。后 19 条规则,是 Scott Meyers 规则。 1) ansi(Function Declarations in ANSI Syntax) 描述:函数的声明和实现必须符合 ANSI 语法。 用意:提高代码的易读性和可移植性。 配置 1:name 函数的所有参数必须命名,并且必须在函数声明中说明各个参数的类型。 配置 2:void 禁止函数的参数为空。 例子: 正确写法 f(int a, char *b); f(int a, char *b) { ...} f(void); 错误写法 f(int, char*); f(a, b) int a; char *b { ...} f(); asscal (don’t use Assignment inside Function Calls) 2) 描述:不允许在函数调用中使用赋值运算符(=, +=, -=, *=, /=, %=, >>=, <<=, &=, |=, ^=,++,--)。 用意:去除有关赋值顺序的不明确性。 配置:无。 例子: 正确写法 n=f(b); b++; 错误写法 n=f(b++); 3) asscon (don’t use Assignment inside conditions) 描述:不允许在 if , while , for , switch 控制指令中的条件表达式中使用赋值运算符(=, +=, -=, *=, /=, %=, >>=, <<=, &=, |=, ^=,++,--)。 用意:这个语句 if(x=y) 是不清楚不明确的,也许有人认为作者想写成 if (x= =y)。 配置:无 例子: 正确写法 x -= dx; 第 1 页 共 20 页 错误写法 if (x -= dx) { ...
if (x) { ... for (i=j=n; i > 0; i--, j--){ ... for (i=j=n; i-- > 0; j--) {.. 4) assexp ( don’t nest assignments inside expressions) 描述:在表达式内部  一个运算数只能被赋值一次。  如果有多个赋值运算符,一个被赋值的运算数能且只能出现在它被赋值的位 置。 用意:去除有关赋值顺序的不明确性 配置:无 例子: 正确写法 错误写法 i = t[i++]; a=b=c+a; i=t[i]=15; 5) blockdecl (place Declarations at the beginning of blocks) 描述:声明必须在语句体的开始处。 用意:代码易读性。 配置:无 例子: 正确写法 错误写法 6) Boolean (don’t use abbreviated Boolean expression) 描述:不允许使用缩写的布尔表达式。 用意:代码易读性 配置:无 例子: 正确写法 AlwaysTrue = true; while (AlwaysTrue == true) { if (test == true) { for (i=1; function_call(i); i++){ 错误写法 while (1) { if (test) { for (i=1; function_call(i); i++) { 7) brkcont (Break and Continue forbidden, except in switch statements) 描述:break 和 continue 指令禁止使用在控制语句(for, do ,while)的条件表达式中。然 而,break 指令被允许使用在 switch 语句的结构体中。 用意:像 goto 一样,这些指令会改变代码的结构。在循环中禁止使用它们将使代码比较 容易理解。 第 2 页 共 20 页
配置:无 例子: 正确写法 错误写法 8) classuese (don’t use methods not known in the user class) 描述:下列表达式都是不允许的:u.v.a, u.v.f(),u.g().a, u.g().f(),表达式 中使用->操作符也是一样。 用意:阻止通过串联(连续的)的调用方法,调用一个在用户类中不知道的类方法(隐 式使用)。 配置:无 例子: 正确写法 错误写法 myWindow.itsButton.push(); Error->pos.line; 9) cmclass (use a single class per code file) 描述:一个代码文件中,每个函数都必须属于一个相同的类。 C 函数被认为属于 main 类。 默认情况下,一个代码文件有一个如下的后缀:*.cc, *.cxx, *.cpp,*.C or *.c。 用意:代码易读性。 配置:使用一个字符串来表示那些需要考虑的代码文件的类型。 例子: 正确写法 错误写法 10) cmdef (code files should not contain class declarations) 描述:代码文件不能包含任何类的声明。 C 函数被认为属于 main 类。 默认情况下,一个代码文件有一个如下的后缀:*.cc, *.cxx, *.cpp,*.C or *.c。 用意:代码易读性。 配置:使用一个字符串来表示那些需要考虑的代码文件的类型。 例子: 正确写法 错误写法 11) condop (the ternary operator (? : ) should not be used) 描述:三重条件操作符? ... : ...禁止使用。 用意:代码易读性。 配置:无 例子: 第 3 页 共 20 页
正确写法 错误写法 12) const (literal constants should not be used) 描述:数字和字符串必须被作为常量声明,而不是被直接作为文字形式在程序中使用。 可以指定允许使用的文字常量。默认情况下允许直接使用"", " ", "0" and "1"。 用意:代码易维护性。 配置:一个字符串列表用来表示允许直接使用的常量。 例子: 正确写法 #define TAB_SIZE 100 enum i_val { ok =7; ko =11}; const char HelloWorld[] = "Hello World.\n"; char tab[TAB_SIZE]; i_val i; ... if (i == ok) { p = HelloWorld;} 错误写法 char tab[100]; int i; ... if (i == 7) { p = "Hello World.\n";} 13) constrcpy (Each class must contain an explicit copy constructor) 描述:每个类都必须明确包含它的拷贝构造函数。 用意:确保作者已经考虑到拷贝该类的对象的方法。 配置:如果使用了字符串“dynalloc”,表示这个规则只有在类的成员中包含指针的时候 才检查。 例子: 错误写法 正确写法 class aClass { ... aClass(const aClass &object); // "const" is optional ... }; 14) constrdef (Each class must contain an explicit default constructor) 描述:每个类都必须明确包含它的默认构造函数。 用意:确保作者已经考虑到初始化该类的方法。 配置: 无 例子: 错误写法 正确写法 class aClass { ... aClass(); ... 第 4 页 共 20 页
}; 15) ctrlblock (Block statements should always be used in control structures) 描述: 在控制语句段(if , for , while , do)中必须使用{} 用意:消除结构范围的不清楚性以及使代码易读易改。 配置: 无 例子: 正确写法 if (x == 0) { return; } else { while (x > min) { x--; } } 错误写法 if (x == 0) return; else while (x > min) x--; 16) delarray (Use square brackets when deleting arrays to ensure full array is deallocated) 描述: 当删除数组时必须使用[]。 用意:确保恰当的内存被释放。 配置: 无 例子: 正确写法 int *table = new int[7]; delete [] table; 错误写法 int *table = new int[7]; delete table; delete [10] table; 局限 1:该规则,在一些复杂的情况下失效(不起作用) 例子 1:: int ** myarray = new int[2]; myarray[0] = new int[10]; delete myarray; // 违反规则 delete myarray[0]; // 不违反规则 例子 2: class A { public: int *tab; ... }; A var; var.tab = new int[10]; delete var.tab; //不违反规则 第 5 页 共 20 页
局限 2:当 new 操作被隐式使用,则规则不起作用 int * create_array(int nb) { return (new int[nb]); } ... int * myarray = create_array(10); delete myarray; // 不违反规则 17) destr(Each class must contain an explicit destructor) 描述:每个类都必须明确包含它的析构函数。 用意:确保作者已经考虑到销毁该类的实例的方法。 配置: 无 例子: 错误写法 正确写法 class aClass { ... ~aClass(aClass &object); ... }; 18) dmaccess (access to a class’ data members should be restricted) 描述: 类的接口必须是纯粹的函数:数据成员的定义被限制。 用意:访问一个对象状态的好的方法是通过它的方法,而不是对象的数据成员。类的数 据成员应当是 private 或者至少是 protected。 配置: 一个字符串的列表对应于禁止访问的数据成员。 例子: 正确写法 错误写法 19) exprcplx (syntactic tree complexity must be limited) 描述: 表达式的复杂度必须小于一个给定的值。复杂度的计算与语法树以及它的节点 个数有关。默认情况下,最大的审核值复杂级为 13。 用意:代码易读性。 配置: 一个数用来表示最大的审核值复杂级 例子: (b+c*d) + (b*f(c)*d) 有 8 个操作符和 7 个操作数.,语法树有 16 个节点,复杂度为 16。 20) exprparenth(Parenthesses should be used to indicate evaluation order) 描述: 在表达式中,每个二元的和三元的操作符必须放在()中。 第 6 页 共 20 页
如果使用参数 partpar,则: 当右边的操作符与当前操作符同是+或者*则,禁止为右边的操作数使用(); 同上,赋值操作符右边的操作数禁止使用(); 禁止在表达式的第一级使用(); 用意:减少运算顺序的不明确性。 配置:参数 partpar 例子: // do not write result = fact / 100 + rem; // write result = ((fact / 100) + rem); // or write, with the partpar option result = (fact / 100) + rem; // with the partpar option, write result = (fact * ind * 100) + rem + 10 + (coeff ** c); // instead of result = ((fact * (ind * 100)) + (rem + (10 + (coeff ** c)))); 21) fntype(Function type must always be declared) 描述: 每个函数必须声明它的类型。如果不返回任何值,它必须被声明为 void 类型。 用意:提高代码的可移植性。 22) forinit (Loop counters must be initialized within the loop) 描述: 循环的计数器(在 for 循环中)必须在循环的初始化语句段中初始化。由循环头 中的第三个元素来判断哪个是循环计数器。 用意:通过这种要求,循环计数器被确保初始化,循环易于理解和控制。 例子: 正确写法 for (int i = 0; i < 10; i++) ... for (int i; i < 10; i++) ... 错误写法 for (int j = 0; j < 10; i++) ... for (int j = 10; i < j; i++) ... for (int j = 1; i < funct(j); i+=j) ... 23) frnclass(Friend classes must be declared at he beginning of th class) 描述: 如果使用友员类,则友员类必须在类的开始处被声明(在类的成员被声明之前)。 24) funcptr(Do not use function pointers) 描述: 不使用函数指针。 例子 1: void print(int i) 第 7 页 共 20 页
{ std::cout << i << std::endl; } void (*func_1)(int); func_1 = &print; func_1( 1); (*func_1)( 1); 例子 2: typedef void (*PFUNC)(int); PFUNC pfunc; 25) funcree(Prohibit specified function names) 描述:特定的名字不能用来声明或者定义函数,也不能调用。默认情况下,不禁止任何 函数名。 用意:禁止使用一些比较危险的系统函数。 配置:一个字符串列表用来表示需要禁止使用的函数名。 例子: // 如果禁止使用 system 函数 //下面的使用违反规则 int system(char *command); int system(char *command) { ... } system("cp file /tmp"); 26) globinit (Global variable must be initialized when they are defined) 描述: 全局变量必须在定义的时候初始化。 用意:不是所有的编译器都给予相同的默认值。可以通过控制变量的值来避免一些不期 望的动作。当声明全局变量的时候就赋初值可以确保在使用它们之前初始化。 27) goto(Prohibit the use of the goto statement) 描述: goto 语句不能使用。 也可以配置某些特定的标签(label)可以使用 goto 用意:确保遵守结构化的编程规则,代码易于理解。 配置:可以使用 goto 的 label 列表 28) Headercom(Modules must be preceded by a structured comment) 描述: 模块必须有一个头注释。头注释的格式依赖于在 meitric 类型中定义的模块类型。 默认情况下,头注释如下: /////////////////////////////////////////// ///// // Name: program // Author: Andrieu // Date: 08/07/96 第 8 页 共 20 页
分享到:
收藏