68.函数的声明应该是在文件的范围内(R)
例如
void myfunc(void) {
extern int call(void); /* 违反规则68 */
}
69.函数不能使用可变参数格式的样式(R)
也就是说函数参数的格式应该固定。这是针对C语言支持可变参数函数而制定的。例如:
extern int myfunc(int *a, …); /* 与规则69冲突*/
70.函数不允许直接或间接的调用自己(R)
这条规定在安全相关软件中,禁止使用递归函数,主要是担心递归会引起栈空间的溢出。
71.函数应该具有函数原型声明,声明对于函数实现和调用的地方是可见的(R)
在函数调用前应该具有明显的声明,尤其是针对跨文件的函数使用。
72.传递给函数的参数应该与函数相应参数的声明一致,并且返回值也应该一致(R)
73.在函数的原型声明中,要么所有的函数参数名称给定,要么都空余(R)
例如:
extern int myfunc(int a, int); /* 与规则冲突73 */
74.如果函数的参数名被给定,那么在函数的声明和定义中,标识符应该一致(R)
75.每一个函数应该具有显式的返回类型(R)
如果没有返回数据,则采用返回void型类型。
76.没有参数的函数声明应该在声明参数的地方用void类型(R)
例如下面给出了一个没有返回数据和没有参数的函数声明方式。
void myfunc(void);
77.传递给函数的无限制类型的参数应该与函数原型中定义的无限制类型相兼容(R)
78.函数参数传递的个数应该与函数原型中的个数相匹配(R)
79.由void函数返回的值不能使用(R)
void myVoid();
int myReturn();
void myFunc() {
int a = 0, b = 0;
a = myVoid(); /* 与规则冲突 */
myVoid(); /* OK */
b = myReturn(); /* OK */
}
80.void表达式不能作为参数传给函数(R)
void foo();
void moo1(int);
void moo2(int,int);
int goo();
void bar () {
void *p;
int a=0;
moo1(a); /* OK */
moo1(foo()); /* 与规则冲突 */
moo2(a,foo()); /* 与规则冲突 */
moo2(a,a); /* OK */
moo1(*p); /* 与规则冲突 */
moo1((void)goo()); /* 与规则冲突 */
}
81.当函数不能修改变量的时候,const限制符应该被用来声明函数的参数(A)
82.一个函数应该具有单一的exit点(A)也就是说函数应该在函数末尾具有exit点。
int foo1(int a) { /* 与规则82冲突 */
if (a>0) {
return 1;
} else {
return 0;
}
}
int foo2(int a) { // Ok
int l;
if (a>0) {
l=1;
} else {
l=0;
}
return l;
}
83.对于不是返回void类型的函数:(R)
i. 对于每一个个exit分支(包含程序的末尾),应该具有一个return语句;
ii. 每一个return都具有一个表达式;
iii. return的表达式应该与返回类型相匹配。
84.对于返回void类型的函数,return语句应该不包含表达式(R)
例如:
void myfunc(void) {
return 0; /* 与规则84冲突 */
}
85.调用没有参数的函数应该具有空括号(A)
例如:
int myfunc(void) {
return 0;
}
int main(int argc, char *argvs[])
{
int a = 0;
a = myfunc; /* 与规则85冲突 */
}
86.如果函数返回错误信息,则错误信息应该被检查(A)
int foo1();
void foo2();
int foo3();
void moo() {
int i;
i=foo1(); /* OK */
foo1(); /* 与规则冲突*/
(void)foo1(); /* OK */
foo2(); /* OK */
if (foo1()!=0) {} /* OK */
if (1) {
foo1(); /*与规则冲突*/
}
if (foo1()) {
foo3(); /*与规则冲突*/
}
}