1 聲明定義類
1.1 過程名禁止被重用
一個過程名禁止被重用于其它之處慢显。
例如:
void foo (unsigned int p_1)
{
unsigned int x=p_1;
}
/***********
* 過程名禁止被重用
***********/
void static_p (void)
{
unsigned int foo=lu;
}
1.2 標(biāo)號名禁止被重用
一個標(biāo)號名被重用掩蓋了這個標(biāo)號名的含義。出現(xiàn)這種情況時(shí),編譯是否通過是依賴于編譯器的差異而不同。
例如:
/***********
*標(biāo)號名禁止被重用
***********/
void static_p (void)
{
unsigned int value_x=lu;
unsigned int y=0u;
/*...*/
value_x:
y=lu;
/*...*/
}
1.3 禁止在結(jié)構(gòu)體定義中含有空域
在結(jié)構(gòu)體定義中禁止含有空域。該準(zhǔn)則的違背通常是出現(xiàn)在類似于如下的使用中:struct atag {struct anothertag {...}; ...};
例如:
/***********
* 禁止在結(jié)構(gòu)體定義中含有空域
**********/
struct s_p (unsigned int xs; struct (unsigned char ac, ab; }; };
void static_p (void)
{
struct s_p sb;
sb.xs=1;
/*...*/
}
1.4 禁止聲明多重標(biāo)號
使用多重標(biāo)號是多余的稳吮,多重標(biāo)號完全可以用一個標(biāo)號來替代。
例如:
/***********
* 禁止聲明多重標(biāo)號
**********/
static void static_p (void)
{
start: begin:
/*...*/
}
1.5 參數(shù)必須使用類型聲明
雖然一些編譯器允許缺省參數(shù)類型井濒,但使用參數(shù)類型說明易于類型匹配的檢查灶似,因此參數(shù)必須使用類型聲明。
例如:
/***********
*參數(shù)必須使用類型聲明
**********/
unsigned int static_p(p_1)
{
unsigned int result;
/*...*/
result=p_1*2;
return result;
}
1.6 在過程聲明中必須對參數(shù)說明
雖然大多數(shù)編譯器允許在過程聲明中省略任何的參數(shù)說明眼虱,但在過程聲明中對參數(shù)進(jìn)行說明易于對過程使用中參數(shù)類型匹配的檢查喻奥,因此在過程聲明中必須對參數(shù)說明。
例如:
/***********
* 在過程聲明中必須對參數(shù)說明
**********/
int static_p();
int static_p (unsigned int p)
{
int x=1;
/*...*/
if (p==0)
{
x=0;
}
return x;
}
1.7 禁止過程參數(shù)只有類型沒有標(biāo)識符
一些編譯器允許過程參數(shù)的說明只有類型而沒有標(biāo)識符捏悬,但這樣的參數(shù)并不能真正地被使用撞蚕,因此禁止過程參數(shù)只有類型沒有標(biāo)識符。
例如:
struct s_type_b {unsigned int xs;};
/***********
* 禁止過程參數(shù)只有類型沒有標(biāo)識符
**********/
void static_p_a (unsigned int p_1, struct s_type_b *);
void static_p_a (unsigned int p_1, struct s_type_b *)
{
/*...*/
}
1.8 禁止在過程參數(shù)表中使用省略號
過程參數(shù)用省略號說明不利于對參數(shù)匹配的分析过牙,因此禁止在過程參數(shù)表中使用省略號甥厦。
例如:
/***********
* 禁止在過程參數(shù)表中使用省略號
**********/
unsigned int static_p (unsigned char* p_1, ...)
{
/*...*/
return lu;
}
1.9 禁止重新定義使用C或C++的關(guān)鍵字
重新定義使用C或C++的關(guān)鍵字,破壞了程序的可讀性寇钉,因此禁止重新定義使用C或C++的關(guān)鍵字刀疙。
例如:
/***********
* 禁止重新定義使用C或C++關(guān)鍵字
**********/
void static_p (void)
{
unsigned int public =0;
unsigned int private =0;
unsigned int protected =0;
unsigned int operator =0;
unsigned int new =0:
unsigned int template =0;
unsigned int virtual =0;
unsigned int delete =0;
unsigned int friend =0;
unsigned int cout =0;
unsigned int cin =0;
unsigned int endl =0;
/*...*/
}
1.10 禁止過程或函數(shù)中的參數(shù)表為空
如果是一個無參數(shù)過程或函數(shù),必須使用func(void)
的形式說明扫倡,禁止使用func()
的形式說明谦秧。
例如:
/***********
* 禁止過程或函數(shù)中的參數(shù)表為空
**********/
void satic_p ( )
{
/*...*/
}
1.11 禁止在同一個宏中使用多個#或##
在同一個宏中使用多于一個的#或##,或同時(shí)使用#和##都是很危險(xiǎn)的撵溃,因此禁止在同一個宏中使用多個#或##疚鲤。
1.12 禁止定義不象函數(shù)的宏
定義帶參數(shù)的宏(類函數(shù)宏)時(shí),宏體必須用括號括起來缘挑。
例如:
#define IF_X (x) if(x){
/***********
*禁止定義不象函數(shù)的宏
**********/
void static_p (void)
{
bool test=true:
IF_X(test)
test=!test;
}
}
1.13 禁止在宏中包含不允許的項(xiàng)
宏只能用于符號常量集歇,類函數(shù)宏,類型限定符以及存儲類說明语淘。宏中不允許含有語句關(guān)鍵字和類型關(guān)鍵字诲宇。
例如:
/***********
* 禁止在宏中包含不允許的項(xiàng)
**********/
#define static_p unsigned int
void test_p (void)
{
static_p x=lu;
/*...*/
}
1.14 禁止重新定義保留字
宏預(yù)處理可以重新定義保留字际歼,但這種做法會引起混淆,因此禁止重新定義保留字姑蓝。
例如:
/***********
* 禁止重新定義保留字
**********/
#define FILE unsigned int
void dummy (void)
{
/*...*/
}
1.15 字符型變量必須明確定義是有符號還是無符號
若對字符型變量不明確定義是否有符號鹅心,則在執(zhí)行時(shí)會作為有符號或無符號的類型使用,因此要求字符型變量必須明確定義是有符號還是無符號纺荧。
例如:
/***********
* 字符型變量必須明確定義是有符號還是無符號
**********/
void static_p (void)
{
char c=‘c’;
/*...*/
}
1.16 禁止對一個名字重新定義
雖然C語言允許在許多不同的上下文中對一個名字重新定義巴帮,但命名的唯一性可使程序增加可讀性,因此禁止對一個名字重新定義虐秋。
例如:
/***********
* 禁止對一個名字重新定義
**********/
unsigned int static_p (void);
struct static_p
{
unsigned int static_p;
unsigned int u_1 ;
};
unsigned int static_p (void)
{
unsigned int var_1;
/*...*/
static_p:
var_1=lu;
/*...*/
returm (var_1);
}
1.17 用typedef自定義的類型禁止被重新定義
改變用戶自定義的類型會引起混滑甚至能導(dǎo)致錯誤,因此用typedef自定義的類型禁止被重新定義垃沦。
例如:
typedef int mytype:
/**********
* 用typedef自定義的類型禁止被重新定義
**********/
void static_p (void)
{
typedef float mytype;
/*...*/
}
1.18 禁止在同一個文件中有#if
而沒有#endif
預(yù)處理語句的#if和#endif禁止分散在不同的文件之中客给。
1.19 禁止數(shù)組沒有邊界限定
禁止使用沒有邊界限定的數(shù)組定義。
例如:
/**********
* 禁止數(shù)組沒有邊界限定
**********/
void static_p (void)
{
unsigned int u_array[]={0, 1, 2};
/*...*/
}
1.20 禁止在#include<......>
中使用絕對路徑名
頭文件路徑應(yīng)該在編譯器的選項(xiàng)中予以設(shè)置說明肢簿,禁止在#include<......>
中使用絕對路徑名靶剑。例如:
/**********
* 禁止在#include<......>中使用絕對路徑名
**********/
#include <C:\VC\include\stdio.h>
void Dummy (void)
{
/*...*/
}
1.21 禁止結(jié)構(gòu)體聲明不完整
結(jié)構(gòu)體的聲明必須要完整地聲明。
例如:
/**********
* 禁止結(jié)構(gòu)體聲明不完整
**********/
struct static_p;
void dummy (void)
{
/*...*/
}
1.22 禁止參數(shù)的聲明形式上不一致
在參數(shù)表的參數(shù)聲明中池充,對所有參數(shù)的類型和變量名的聲明形式上必須保持一致桩引。推薦使用僅對參數(shù)類型進(jìn)行聲明的形式。
例如:
/**********
* 禁止參數(shù)的聲明形式上不一致
**********/
float static_p (unsigned int, unsigned short p_2);
2 版面書寫類
2.1 過程體必須用大括號括起來
基于加強(qiáng)代碼可讀性收夸、避免人為失誤的目的坑匠,過程體必須用大括號括起來。
2.2 循環(huán)體必須用大括號括起來
基于加強(qiáng)代碼可讀性卧惜、避免人為失誤的目的厘灼,循環(huán)體必須用大括號括起來。例如:
/**********
* 循環(huán)體必須用大括號括起來
*********/
int static_p(int p_1)
{
int j=10;
int k=0;
/*...*/
for (k=0; k<10; k=k+1) j--;
return;
}
2.3 then/else中的語句必須用大括號括起來
基于加強(qiáng)代碼可讀性咽瓷、避免人為失誤的目的设凹,then/else中的語句必須用大括號括起來。
例如:
/**********
*then/else中的語句必須用大括號括起來
*********/
int static_p (int p_1, int p_2)
{
int i=;
int j=2;
/*...*/
if (p_1>0) {
i=i-1;
} else
i=i+1;
if (p_2>0) {
j=j+p_2;
} else if (p_2<0){
j-j-p_2;
}else{
j=i;
}
return i;
}
2.4 邏輯表達(dá)式的連接必須使用括號
在含有邏輯操作符的表達(dá)式中使用括號可使運(yùn)算順序變得清晰茅姜,且不容易出錯闪朱,因此邏輯表達(dá)式的連接必須使用括號。
例如:
/**********
* 邏輯表達(dá)式的連接必須使用括號
*********/
void static_p (void)
{
bool flag=true;
unsigned int y=Ou, x=Ou, z=lu;
/*...*/
if (x<0 || z+y!=0&&!flag)
{
flag=false;
}
}
2.5 禁止在頭文件前有可執(zhí)行代碼
頭文件應(yīng)放在文件開始的地方钻洒,應(yīng)在任何可執(zhí)行代碼之前奋姿。
例如:
/**********
* 禁止在頭文件前有可執(zhí)行代碼
*********/
void static_p (void)
{
#include " myfile.h"
/*...*/
}
2.6 宏參數(shù)必須用括號括起來
宏體內(nèi)使用的參數(shù)必須用括號括起來。
例如:
/**********
* 宏參數(shù)必須用括號括起來
*********/
#define static_p(x) x>=0?x:-x
void test_p (void)
{
unsigned int result;
int a=6, b=5;
/*...*/
result=static_p(a-b);
result=static_p(a)+1;
/*...*/
}
2.7 嵌入?yún)R編程序的過程必須是純匯編程序
該準(zhǔn)則是為了確保所有插入的代碼是有界面定義的純過程航唆。
例如:
/**********
* 恢入?yún)R編程序的過程必須是純匯編程序
*********/
void static_p (void)
{
unsigned int x;
x=0u;
_asm
{
mov eax, x
}
}
2.8 頭文件名禁止使用“‘”
胀蛮、“\”
和“/*”
等字符
頭文件名使用“‘”
、“\”
和“/*”
等字符會帶來隱含的沖突,因此頭文件名禁止使用“‘”
斩箫、“\”
和“/*”
等字符。
2.9 禁止字符串中單獨(dú)使用“\”
栋齿,字符串的終止必須使用“\0”
只用“\”
并不能控制字符串的終止再榄,應(yīng)該用“\0”
控制字符串的終止狡刘。
例如:
/**********
* 禁止字符串中單獨(dú)使用“\”,字符串的終止必須使用“\0”
*********/
void static_p (void)
{
unsigned char* str=(unsigned char*) " string\
literal";
/*...*/
}
2.10 main須定義為int main(void)
或 int main(int,char* [])
的形式
main須定義為int main(void)
或 int main(int,char* [])
的形式的形式困鸥,這有助于錯誤的確定和參數(shù)的輸入嗅蔬。
例如:
/**********
* main須定義為 int main(void)或int main(int, char* [])的形式
*********/
void static_p (void)
{
/*...*/
}
3 分支控制類
3.1 禁止條件判別成立時(shí)相應(yīng)分支無執(zhí)行語句
條件判別成立時(shí)相應(yīng)分支中無任何執(zhí)行語句疾就,可能是由于疏忽而遺漏掉了澜术,或是有意避免布爾表達(dá)式不成立時(shí)的情況。為了防止由于疏忽造成的遺漏猬腰,因此禁止條件判別成立時(shí)相應(yīng)分支無執(zhí)行語句鸟废。
該準(zhǔn)則的違背通常為下面幾種形式:
a) if(...)else
b) if(...) { } else
c) if(...) {; } else
例如:
/**********
* 禁止條件判別成立時(shí)相應(yīng)分支無執(zhí)行語句
*********/
void static_p (void)
{
unsigned int value_x=lu;
/*...*/
if (value_x==Ou);
/*...*/
if (value_x==0u) {
#if FALSE
value_x=value_x+lu;
#endif
}
/*...*/
if (value_x==0u) {;}
}
3.2 在if...else if語句中必須使用else分支
在if...else if語句中為了表明已經(jīng)考慮了所有情況,必須使用else分支姑荷。
例如:
/**********
* 在if...else if語句中必須使用else分支
*********/
void static_p (void)
{
unsigned int x=2u;
/*...*/
if (x= =2u) {
/*...*/
} else if (x= =3u) {
/*...*/
}
}
3.3 禁止條件判別的else分支無可執(zhí)行語句
else分支中無可執(zhí)行語句或是由于代碼不完整造成的盒延,或是有意表明else對應(yīng)的可能性已經(jīng)考慮到,了鼠冕。為了防止殘留不完整的代碼添寺,因此禁止條件判別的else分支無可執(zhí)行語句。
該準(zhǔn)則的違背通常為下面幾種形式:
a) else懈费;
b) else { }
c) else {; }
例如:
/**********
* 禁止條件判別的else分支無可執(zhí)行語句
*********/
void static_p (void)
{
unsigned int name_x=lu;
/*...*/
if (name_x= =0u)
{/*...*/}
else;
/*...*/
if (name_x= =0u)
{/*...*/}
else
{
#if FALSE
name_x=name_x+lu;
#endif
}
/*...*/
if (name_x= =0u)
{/*...*/}
else
{;}
}
3.4 在switch語句中必須有default語句
如果switch語句中缺省了default語句计露,當(dāng)所有的case語句的表達(dá)式值都不匹配時(shí),則會跳轉(zhuǎn)到整個switch語句后的下一個語句執(zhí)行楞捂。強(qiáng)制default語句的使用體現(xiàn)出已考慮了各種情況的編程思想薄坏。
例如:
/**********
* 在switch語句中必須有default語句
*********/
void static_p (int p_1)
{
int i=0, j=0;
/*...*/
switch (p_1)
{
case 0:
j=0;
break;
case 1:
j=i;
break;
}
/*...*/
}
3.5 禁止使用空 switch語句
空switch語句不具備任何實(shí)際的操作內(nèi)容,因此禁止使用空switch語句寨闹。
例如:
/**********
* 禁止使用空switch語句
*********/
void static_p (int p_1)
{
int i=p_l;
switch (i)
{
}
}
3.6 禁止switch 語句中只包含default語句
如果switch語句中只包含default語句胶坠,則該switch語句的使用無任何實(shí)際價(jià)值,因此禁止switch語句中只包含default語句繁堡。
例如:
/**********
* 禁止switch 語句中只包含default語句
*********/
void static_p (int p_1)
{
int i=p_l;
switch (i)
{
default;
i++;
}
}
3.7 禁止switch的case語句不是由break終止
如果某個case語句最后的break被省略沈善,在執(zhí)行完該case語句后,系統(tǒng)會繼續(xù)執(zhí)行下一個case語句椭蹄。case語句不是有break終止闻牡,有可能是編程者的粗心大意,也有可能是編程者的特意使用绳矩。為了避免編程者的粗心大意罩润,因此禁止switch的case語句不是由break終止。
例如:
/**********
* 禁止switch的case語句不是由break終止
*********/
void static_p (int p_1)
{
int i=0, j=0;
switch (p_1)
{
case 0:
j=0;
case 1:
j=i;
break;
default:
i=j+1;
}
/*...*/
}
3.8 禁止switch的case語句中無任何可執(zhí)行語句
如果某個case語句中無任何可執(zhí)行語句翼馆,則它將共享后面case語句中的執(zhí)行語句割以。這種情況或是由于代碼不完整造成的金度,或是編程者特意設(shè)計(jì)的。為了防止殘留不完整的代碼严沥,因此禁止switch的case語句中無任何可執(zhí)行語句猜极。
例如:
/**********
* 禁止switch的case語句中無任何可執(zhí)行語句
*********/
int static_p (int p_1)
{
int i=0, j=0;
/*...*/
switch (p_1)
{
case 0:
j=0;
break;
case 1:
case 2:
j=i;
break;
default:
i=j+1;
}
return i+j;
}
4 指針使用類
4.1 禁止將參數(shù)指針賦值給過程指針
將參數(shù)指針賦值給過程指針會導(dǎo)致不可預(yù)料的結(jié)果,因此禁止將參數(shù)指針賦值給過程指針消玄。
例如:
/**********
* 禁止將參數(shù)指針賦值給過程指針
*********/
unsigned int *static_p (unsigned int *pl_ptr)
{
static unsigned int w=10u;
/*...*/
pl_ptr=&w;
/*...*/
return &w;
}
4.2 禁止指針的指針超過兩級
對指針進(jìn)行控制是很困難的跟伏,當(dāng)指針的指針超過兩級時(shí),使用起來更是具有風(fēng)險(xiǎn)翩瓜,因此禁止指針的指針超過兩級受扳。
例如:
/**********
* 禁止指針的指針超過兩級
*********/
void static_p (void)
{
unsigned int array[10]={0};
unsigned int *pl_ptr, **p2_ptr;
unsigned int **p3_ptr;
unsigned int w;
pl_ptr=array;
p2_ptr=&pl_ptr;
p3_ptr=&p2_ptr;
w=**p3_ptr;
}
4.3 禁止將過程聲明為指針類型
使用過程指針是具有較大風(fēng)險(xiǎn)的,因此禁止將過程聲明為指針類型兔跌。
例如:
void foo (unsigned int p_1, unsigned short p_2)
{/*...*/};
/**********
* 禁止將過程聲明為指針類型
*********/
void static_p (void)
{
void (*proc_pointer) (unsigned int, unsigned short) =foo;
proc_pointer (lu, 1);
/*...*/
}
5 跳轉(zhuǎn)控制類
5.1 禁止直接從過程中跳出
直接從過程中跳出破壞了程序的結(jié)構(gòu)化辞色,因此禁止直接從過程中跳出。
例如:
#include <set jmp.h>
/**********
* 禁止直接從過程中跳出
*********/
static void static_p (jmp_buf mark, unsigned int val)
{
longjmp (mark, val);
}
5.2 禁止使用goto 語句
使用goto語句是不好的編程習(xí)慣浮定, goto語句破壞了程序的結(jié)構(gòu)化,因此禁止使用goto語句层亿。
例如:
/**********
* 禁止使用goto 語句
*********/
void static_p (void)
{
int jump_flag=0;
/*...*/
start:
jump_flag++;
if (jump_flag<10) {
goto start;
}
}
6 運(yùn)算推薦類
6.1 禁止在非賦值表達(dá)式中出現(xiàn)賦值操作符
在非賦值表達(dá)式中出現(xiàn)賦值操作符桦卒,可能是由于將“==”誤寫為“=”造成的,這會引起無法預(yù)料的后果匿又,因此禁止在非賦值表達(dá)式中出現(xiàn)賦值操作符方灾。
例如:
/**********
* 禁止在非賦值表達(dá)式中出現(xiàn)賦值操作符
*********/
void static_p (void)
{
unsigned int z=0u, x=0u;
bool flag=true;
/*...*/
if (flag=false) {
z=x-lu;
}
/*...*/
}
6.2 數(shù)組的使用必須保證不會出現(xiàn)越界
該準(zhǔn)則的違背通常是下標(biāo)超出了數(shù)組所指定的范圍。
例如:
/**********
* 數(shù)組的使用必須保證不會出現(xiàn)越界
*********/
void static_p (void)
{
unsigned int a[4] /
/*...*/
a[5]=1;
/*...*/
}
6.3 禁止對有符號類型進(jìn)行移位運(yùn)算
對有符號類型進(jìn)行移位運(yùn)算會導(dǎo)致不可預(yù)料的后果碌更。
例如:
/**********
* 禁止對有符號類型進(jìn)行移位運(yùn)算
*********/
void static_p (void)
{
int b=1;
/*...*/
b>>=1;
}
6.4 對變量進(jìn)行移位運(yùn)算必須保證不會產(chǎn)生溢出
一些編譯器不檢查移位運(yùn)算是否超出機(jī)器字長裕偿。
例如:
/**********
* 對變量進(jìn)行移位運(yùn)算必須保證不會產(chǎn)生溢出
*********/
void static_p (void)
{
unsigned int x=0u;
unsigned int y=2u;
/*...*/
x=y<<34;
}
6.5 禁止給無符號變量賦負(fù)值
給無符號變量賦負(fù)值會導(dǎo)致不可預(yù)料的結(jié)果,因此禁止給無符號變量賦負(fù)值痛单。
例如:
/**********
* 禁止給無符號變量賦負(fù)值
*********/
void static_p (void)
{
unsigned int x=1u;
unsigned int y=2u;
/*...*/
y=-x;
}
6.6 有符號類型的位長度必須大于等于兩位
有符號類型只給一位的長度是沒有意義的嘿棘,因此有符號類型的位長度必須大于等于兩位。
例如:
/**********
* 有符號類型的位長度必須大于等于兩位
*********/
struct static_p{int x:1;};
void dummy (void)
{
/*...*/
}
6.7 位的定義必須是有符號整數(shù)或無符號整數(shù)
位不能定義為有符號或無符號整數(shù)之外的其它類型旭绒。
例如:
/**********
* 位的定義必須是有符號整數(shù)或無符號整數(shù)
*********/
struct static_p {unsigned char x:1; };
void dummy (void)
{
/*...*/
}
6.8 禁止給變量賦的值與變量的類型不一致
給變量賦的值與變量的類型不一致會導(dǎo)致數(shù)值有效位的損失鸟妙。
例如:
/**********
* 禁止給變量賦的值與變量的類型不一致
*********/
void static_p (void)
{
unsigned int d;
d=2.0; /* Requires explicit assignment of 2u */
/*...*/
}
6.9 賦值類型必須匹配
賦值類型不匹配會導(dǎo)致數(shù)值有效位的損失。
例如:
/**********
* 賦值類型必須匹配
*********/
void static_p (void)
{
float fl=2.0f;
double dbl=3.0;
/*...*/
fl=dbl;
}
6.10 數(shù)組下標(biāo)必須是整型數(shù)
數(shù)組下標(biāo)表示數(shù)組元素的序號挥吵,所以數(shù)組下標(biāo)必須是整型數(shù)重父。
例如:
#define ArraySize 3.0f
/**********
* 數(shù)組下標(biāo)必須是整型數(shù)
*********/
void static_p (void)
{
unsigned int fl_arr[ArraySize]={0, 1, 2};
}
6.11 禁止對常數(shù)值做邏輯非的運(yùn)算
對常數(shù)值做邏輯非的運(yùn)算會使得邏輯判別思路混亂。
例如:
/**********
* 禁止對常數(shù)值做邏輯非的運(yùn)算
*********/
void static_p (void)
{
bool flag=false;
if(flag==!1)
{
/*...*/
}
}
6.12 禁止對有符號類型使用位運(yùn)算
位運(yùn)算對有符號的數(shù)是很危險(xiǎn)的忽匈,因?yàn)榉栁粫诲e誤地改變房午。
例如:
/**********
* 禁止對有符號類型使用位運(yùn)算
*********/
void static_p (void)
{
int b=1;
/*...*/
b=b | 1;
/*...*/
}
6.13 禁止對枚舉類型的越限使用
枚舉類型只能用于與其它枚舉類型進(jìn)行比較,禁止對枚舉類型的越限使用丹允。
例如:
/**********
* 禁止對枚舉類型的越限使用
*********/
void static_p (void)
{
enum E_type (Enum1, Enum2, Enum3);
unsigned int ui;
ui=Enum1;
/*...*/
}
6.14 變量的使用禁止超出所定義的范圍
變量在運(yùn)算過程應(yīng)確保不會發(fā)生超界的數(shù)據(jù)溢出郭厌,對安全關(guān)鍵變量必須要仔細(xì)進(jìn)行值域檢查袋倔。
6.15 禁止在邏輯表達(dá)式中使用賦值操作符
在邏輯表達(dá)式中使用賦值操作符,可能是由于將“==”誤寫為“=”造成的沪曙,這會引起無法預(yù)料的后果奕污,因此禁止在邏輯表達(dá)式中使用賦值操作符。
例如:
/**********
* 禁止在邏輯表達(dá)式中使用賦值操作符
*********/
void static_p (void)
{
bool flag=false;
if (flag=false) /* This condition should be (flag= =false)*/
{
/*...*/
}
}
6.16 禁止賦值操作符與“&&”或“||”連用
這種用法是一種不好的編程習(xí)慣液走,因?yàn)橘x值被條件化了碳默,原期望的賦值未必能被執(zhí)行,因此禁止賦值操作符與“&&”或“||”連用缘眶。
例如:
/**********
* 禁止賦值操作符與“&&”或“||”連用
*********/
void static_p (void)
{
bool flag=false;
unsigned int y=0u, x=0u;
/*...*/
if (flag && ((x=y) ==0)){
/*...*/
}
}
6.17 禁止位操作符帶有布爾型的操作數(shù)
這種情況的出現(xiàn)通常是用錯了操作符號嘱根,例如把“||”誤寫為“!”巷懈。
例如:
/**********
* 禁止位操作符帶有布爾型的操作數(shù)
**********/
void static_p (void)
{
unsigned int x=lu;
bool flag=false;
/*...*/
if((flag | (x!=0)) ==false) {
/*...*/
}
}
6.18 禁止位操作符作用于布爾值
這種情況的出現(xiàn)通常是用錯了操作符號该抒,例如把“&&”誤寫為“&”。
例如:
/**********
* 禁止位操作符作用于布爾值
**********/
void static_p (void)
{
unsigned int y=2u;
bool flag=false;
flag=flag & (y==2u);
}
7 過程調(diào)用類
7.1 實(shí)參與形參的個數(shù)必須一致
一些編譯連接器忽略實(shí)參與形參的個數(shù)檢查顶燕。為了防止實(shí)參與形參匹配的錯誤凑保,強(qiáng)制要求實(shí)參與形參的個數(shù)必須一致。
例如:
unsigned int test_p (unsigned int p_1, unsigned short p_2)
{
unsigned int result=0u;
/*...*/
result=p_1+p_2;
return result;
}
/**********
* 實(shí)參與形參的個數(shù)必須一致
**********/
void static_p (unsigned int p_1, unsigned short p_2)
{
test_p(lu, 2, 3);
}
7.2 主過程所在文件中禁止有未被該文件中任何過程調(diào)用的子過程
主過程所在文件中如果有未被該文件中任何過程調(diào)用的子過程涌攻,那么這個子過程有可能被其它文件中的過程所調(diào)用欧引,應(yīng)該把這個子過程移到有過程調(diào)用它的那個文件中去。
例如:
/**********
* 主過程所在文件中禁止有未被該文件中任何過程調(diào)用的子過程
**********/
unsigned int static_p (unsigned int p)
{
unsigned int x =lu;
/*....*/
x=x+p;
return x;
}
int main (void)
{
/*...*/
return(0);
}
7.3 static類型的過程在所在文件中必須被調(diào)用
如果一個過程被聲明為static的類型恳谎,那么它的作用域?yàn)樗谖募ゴ恕H羲谒谖募袥]被調(diào)用,就應(yīng)該把它去掉因痛。
例如:
static bool static_p (unsigned int);
/**********
* static類型的過程在所在文件中必須被調(diào)用
**********/
static bool static_p (unsigned int p_1)
{
bool ret=false;
unsigned int i=p_1+lu;
/*...*/
if (j==0){
ret=true;
}
return ret;
}
void main (void)
{
/*...*/
}
7.4 禁止使用被禁用的過程婚苹、函數(shù)、文件或名稱
由于某些原因鸵膏,有許多被禁止使用的一些特殊項(xiàng)膊升,如:
a)庫中的過程或函數(shù);
b)庫文件谭企;
c)特定的名稱用僧。
7.5 在不能使用 extern的文件中禁止使用 extern
在一些文件中對extern的使用有嚴(yán)格限制,必須保證在不能使用extern的文件中禁止使用extern赞咙。
例如:
/**********
* 在不能使用extem的文件中禁止使用extern
**********/
/* any extern to be forbidded */
extern unsigned int undef_global;
void static_p (void)
{
undef_global=lu;
}
7.6 禁止同一個表達(dá)式中調(diào)用多個相關(guān)函數(shù)
如果同一個表達(dá)式中調(diào)用多個相關(guān)函數(shù)责循,可能會因執(zhí)行的順序不同而產(chǎn)生不同的結(jié)果,因此禁止同一個表達(dá)式中調(diào)用多個相關(guān)函數(shù)攀操。
例如:
unsigned int exp_1 (unsigned int *p_1)
{
unsigned int x=*p_l;
(*p_1) =x*x;
return (x);
}
unsigned int exp_2 (unsigned int *p_1)
{
unsigned int x=*p_1;
(*p_1)=(x %2);
return (x);
}
/**********
* 禁止同一個表達(dá)式中調(diào)用多個相關(guān)函數(shù)
**********/
void static_p (void)
{
unsigned int y=3u, x=0u;
x=exp_i (&y) +exp_2 (&y);
}
7.7 禁止void類型的過程用在表達(dá)式中使用
返問類型說明為void的過程用在表達(dá)式中使用是危險(xiǎn)的院仿,因此禁止void類型的過程用在表達(dá)式中使用。
例如:
void foo (void)
{
/*...*/
}
/**********
* 禁止void類型的過程用在表達(dá)式中使用
**********/
void static_p (void)
{
char x;
x=(char) foo ();
}
7.8 禁止void類型的變量作為參數(shù)進(jìn)行傳遞
傳遞void類型的參數(shù)會導(dǎo)致不可預(yù)料的結(jié)果,因此禁止:void類型的變量作為參數(shù)進(jìn)行傳遞歹垫。
例如:
void void_para_func (void *p_1)
{
/*...*/
}
/**********
* 禁止void類型的變量作為參數(shù)進(jìn)行傳遞
**********/
void static_p (unsigned int p_1, unsigned short p_2)
{
int y=0;
void *v_ptr=&y;
y=(int) (p_1+p_2);
void_para_func (v_ptr);
}
7.9 禁止實(shí)參和形參類型不一致
為了嚴(yán)格的參數(shù)類型匹配檢查剥汤,因此禁止實(shí)參和形參類型不一致。
例如:
void foo (unsigned short p_1, unsigned short p_2)
{
/*...*/
}
/**********
* 禁止實(shí)參和形參類型不一致
**********/
void static_p (unsigned int p_1, unsigned short p_2)
{
foo (p_1, p_2);
/*...*/
}
7.10 函數(shù)和原型參數(shù)類型必須一致
為了嚴(yán)格的函數(shù)類型匹配檢查排惨,因此函數(shù)和原型參數(shù)類型必須一致吭敢。
例如:
bool static_103 (float up_1);
/**********
*函數(shù)和原型參數(shù)類型必須一致
**********/
bool static_p (unsigned int up_1)
{
bool ret=false;
/*...*/
return ret;
}
8 語句使用類
8.1 禁止單獨(dú)使用小寫字母“1”或大寫字母“0”作為變量名
小寫字母“1”很容易與數(shù)字“1”混浠,大寫字母“O”很容易與數(shù)字“0”混淆暮芭,因此禁止單獨(dú)使用小寫字母“1”或大寫字母“O”作為變量名鹿驼。
例如:
/**********
* 禁止單獨(dú)使用小寫字母“1”或大寫字母“O”作為變量名
**********/
void static_p (void)
{
int l=1, O=0;
/*...*/
1=0;
O=1;
}
8.2 禁止三字母詞的使用
三字母詞的使用使得程序難于閱讀,容易出現(xiàn)編程失誤辕宏。
例如:
/**********
* 禁止三字母詞的使用
**********/
void static_p (void)
{
??</*??(在這里代替(*/
/*...*/
}
8.3 使用的八進(jìn)制數(shù)必須加以注釋
由于八進(jìn)制數(shù)是以0開始的畜晰,容易與十進(jìn)制的數(shù)混澤,所以使用的八進(jìn)制數(shù)必須加以注釋瑞筐。
例如:
/**********
* 使用的八進(jìn)制數(shù)必須加以注釋
**********/
void static_p (void)
{
unsigned int i;
i=(unsigned int) 076;
/*...*/
}
9 調(diào)用返回類
9.1 函數(shù)必須有返回語句
一個函數(shù)應(yīng)該有一個返回語句凄鼻,否則函數(shù)會返回一個隨機(jī)數(shù),這個隨機(jī)數(shù)通常是堆棧頂端值聚假。
例如:
/**********
* 函數(shù)必須有返回語句
**********/
unsigned int static_p (unsigned int p_1, unsigned short p_2)
{
unsigned int y=p_1;
/* Not returning a value */
}
9.2 禁止void類型的過程中的return語句帶有返回值
如果過程返同類型為void块蚌,則該過程的設(shè)計(jì)本身就是無返回類型值的,因此禁止void類型的過程中的return語句帶有返回值膘格。
例如:
/**********
* 禁止void類型的過程中的return 語句帶有返回值
**********/
void static_p(unsigned int p_1, unsigned int p_2)
{
unsigned int result;
/*...*/
result=p_1+p_2;
return result;
}
9.3 有返回值的函數(shù)中return必須帶有返回值
有返回值的函數(shù)中如果只有return語句而無具體的指定值匈子,則此時(shí)將返回一個隨機(jī)數(shù)。
例如:
/**********
* 有返問值的函數(shù)中return必須帶有返回值
**********/
unsigned int static_p (unsigned int p_1, unsigned short p_2)
{
/*...*/
return;
}
9.4 函數(shù)返回類型必須一致
既然依據(jù)設(shè)計(jì)定義了函數(shù)的返回類型闯袒,則函數(shù)的實(shí)際返回類型必須與定義的返回類型相一致。
例如:
/**********
* 函數(shù)返回類型必須一致
**********/
unsigned int static_p (unsigned int par_1)
{
switch (par_1) {
case 0:
return (-1);
break;
case 1:
return (1u);
break;
case 2:
return (1L);
break;
case 3:
return (1.0f);
break;
default:
break;
}
}
9.5 函數(shù)和原型返回類型必須一致
既然依據(jù)設(shè)計(jì)聲明了原型的返回類型游岳,則函數(shù)的返回類型必須與原型的返回類型相一致政敢。
例如:
float static_102 (unsigned int, unsigned short);
/**********
* 函數(shù)和原型返回類型必須一致
**********/
int static_p (unsigned int p_1, unsigned short p_2)
{
int result=0;
/*...*/
return result;
}
10 程序注釋類
10.1 禁止使用嵌套的注釋
嵌套注釋是否通過依賴于具體的編譯器,同時(shí)嵌套注釋也影響了程序的可讀性胚迫,所以禁止使用嵌套的注釋喷户。
例如:
/**********
* 禁止使用恢套的注釋
**********/
void static_p (void)
{
/* This is the Outer Comment
/* This is the Inner Comment
*/
}
11 循環(huán)控制類
11.1 禁止使用不合適的循環(huán)變量類型
有許多類型不適合用于循環(huán)變量,尤其是實(shí)型變量访锻。
例如:
/**********
* 禁止使用不合適的循環(huán)變量類型
**********/
void static_p (void)
{
float f=0.0f;
/*...*/
for (f=0.0f; f<10.0f; f=f+1.0f){
/*...*/
}
}
11.2 循環(huán)變量必須是局部聲明的
循環(huán)變量應(yīng)該定義在最小的范圍內(nèi)褪尝,即循環(huán)變量的作用域應(yīng)最小,所以循環(huán)變量必須是局部聲明的期犬。
例如:
unsigned int global_f=0u:
/**********
* 循環(huán)變量必須是局部聲明的
**********/
int loop_standards (int p_1)
{
int j=10;
/*...*/
for (global_f=0; global_f<10; global_f=global_f+1) {
j--;
}
return j;
}
12 類型轉(zhuǎn)換類
12.1 禁止對指針變量使用強(qiáng)制類型轉(zhuǎn)換賦值
強(qiáng)制將其它類型轉(zhuǎn)換為指針類型是很危險(xiǎn)的河哑,因此禁止對指針變量使用強(qiáng)制類型轉(zhuǎn)換賦值。
例如:
/**********
* 禁止對指針變量使用強(qiáng)制類型轉(zhuǎn)換賦值
**********/
void static_p (void)
{
unsigned short s=0;
unsigned int *pl_ptr;
pl_ptr=(unsigned int *)s;
/*...*/
}
13 初始化類
13.1 枚舉元素的初始化必須完整
枚舉類型的初始化只有兩種形式是安全的龟虎。一是初始化所有的元素璃谨,二是只初始化第一個元素。
例如:
/**********
* 枚舉元素的初始化必須完整
**********/
void static_p(void)
{
enum E_type {numl, num2=2, num3};
/*...*/
}
13.2 結(jié)構(gòu)體變量初始化的類型必須一致
結(jié)構(gòu)體變量的初值類型必須與結(jié)構(gòu)體變量的定義類型一致。
例如:
struct s_type_a{int xs; float fs; };
/**********
* 結(jié)構(gòu)體變量初始化的類型必須一致
**********/
void static_p (void)
{
struct s_type a sta={3.14f. 0.0f};
/*...*/
}
13.3 結(jié)構(gòu)體變量初始化的嵌套結(jié)構(gòu)必須與定義的相一致
通常是編程者疏忽了結(jié)構(gòu)中的結(jié)構(gòu)變量的嵌套層次關(guān)系佳吞,在對結(jié)構(gòu)體變量初始化時(shí)必須要保持與定義的嵌套結(jié)構(gòu)相一致拱雏。
例如:
struct pixel (unsigned int colour: struct {unsigned int x, y:} coords;};
/**********
* 結(jié)構(gòu)體變量初始化的長套結(jié)構(gòu)必須與定義的相一致
**********/
void static_p (void)
{
unsigned int xs=0u;
unsigned int ys=0u;
struct pixel spot= {u, xs, ys};
/*...*/
}
13.4 變量使用前必須被賦過值
在使用變量前應(yīng)確保變量已被賦值。例如:
unsigned int x;
unsigned int y;
y=x底扳;
其中對變量x的使用铸抑,在使用前未被賦值。
如果變量是在某些條件前提下進(jìn)行的賦值衷模,在條件結(jié)束后使用該變量鹊汛,則同樣是違背該條準(zhǔn)則。
14 比較判斷類
14.1 禁止對實(shí)數(shù)類型的量做是否相等的比較
對實(shí)數(shù)類型的量做是否相等的比較是很危險(xiǎn)的算芯,因?yàn)閷?shí)數(shù)類型的量完全相等的幾率是很小的柒昏。
例如:
/**********
* 禁止對實(shí)數(shù)類型的量做足否相等的比較
**********/
void static_p (void)
{
float fl, f2;
fl=1.01f;
f2=2.01f;
/*...*/
if(fl= =f2){
/*...*/
}
if (fl==0.0f) {
fl=fl+0.01f;
}
}
14.2 禁止邏輯判別的表達(dá)式不是邏輯表達(dá)式
邏輯判別的表達(dá)式應(yīng)是邏輯表達(dá)式,邏輯表達(dá)式才真正體現(xiàn)了邏輯的判別熙揍。通常該準(zhǔn)則的違背是在應(yīng)使用邏輯表達(dá)式的地方使用了整數(shù)表達(dá)式职祷。
例如:
/**********
* 禁止邏輯判別的表達(dá)式不是邏輯表達(dá)式
**********/
void static_p (void)
{
unsigned int x=0u;
if(x){
/*...*/
}
}
14.3 switch 語句中的表達(dá)式禁止是邏輯表達(dá)式
因?yàn)檫壿嫳磉_(dá)式只有真和假兩種情況,當(dāng)需要對邏輯表達(dá)式判別時(shí)届囚,應(yīng)使用if then else語句有梆,而不應(yīng)是switch語句。
例如:
/**********
* switch語句中的表達(dá)式禁止是邏輯表達(dá)式
**********/
void static_p (void)
{
bool flag=false;
/*...*/
switch (flag) {
case true:
/*...*/
break;
case false:
/*...*/
break;
default:
break;
}
}
15 名稱意系、符號與變量使用類
15.1 禁止枚舉類型中的元素名與已有的變量名同名
枚舉類型中的元素名應(yīng)保持唯一性泥耀。該準(zhǔn)則的違背通常表現(xiàn)在,枚舉中元素名與已有的全局變量名同名蛔添。
例如:
unsigned int duplicate=0u;
/**********
* 禁止枚舉類型中的元素名與已有的變量名同名
**********/
void static_p (void)
{
enum Name_type {el, duplicate} EnumVar;
EnumVar=el;
/*...*/
}
15.2 禁止局部變量與全局變量同名
C語言編譯器是允許局部變量與全局變量同名痰催,但局部變量的作用域只限制在聲明的模塊內(nèi)部。為避免本意是需要對全局變量更新迎瞧,但由于存在同名的局部變量夸溶,導(dǎo)致全局變量未得到實(shí)際有效的更新,因此禁止局部變量與全局變量同名凶硅。
例如:
unsigned int Fire_Command:
/**********
* 禁止局部變量與全局變量同名
**********/
void static_p (void)
{
unsigned int Fire_Command=2u;
……
}
15.3 禁止形參名與全局變量名同名
形參名與全局變量名同名使程序的可讀性降低缝裁,且容易出現(xiàn)編程失誤,因此禁止形參名與全局變量名同名足绅。
例如:
/*--Global Declarations --*/
unsigned int global_int=0;
/**********
* 禁止形參名與全局變量名同名
**********/
void static_p (unsigned int *global_int)
{
/*...*/
}
15.4 禁止形參名與類型或標(biāo)識符同名
形參名與類型或標(biāo)識符同名使程序的可讀性降低捷绑,且容易出現(xiàn)編程失誤,因此禁止形參名與類型或標(biāo)識符同名氢妈。
例如:
typedef unsigned int DUPLICATE;
/**********
* 禁止形參名與類型或標(biāo)識符同名
**********/
void static_p (unsigned int DUPLICATE)
{
/*...*/
}
15.5 禁止在內(nèi)部塊中重定義已有的變量名
塊結(jié)構(gòu)允許在內(nèi)部塊中重定義已有的變量名粹污,但這是不好的編程習(xí)慣,且容易出現(xiàn)編程失誤首量,因此禁止在內(nèi)部塊中重定義已有的變量名厕怜。
例如:
/**********
* 禁止在內(nèi)部塊中重定義已有的變量名
**********/
void static_p (unsigned int p_1)
{
unsigned int static_p;
bool c_1=false;
/*...*/
if(c_1){
unsigned int static_p=1u;
/*...*/
static_p=static_p+lu;
} else{
static_p=p_1;
}
/*...*/
}
15.6 禁止復(fù)雜表達(dá)式中使用volatile類型的變量
volatile類型變量的值可以被隨意地改變,因此只在簡單的表達(dá)式中使用它才是安全的,而在復(fù)雜表達(dá)式中禁止使用volatile類型的變量粥航。
例如:
/**********
*禁止復(fù)雜表達(dá)式中使用volatile類型的變量
**********/
void static_p (void)
{
unsigned int y=0u; x=0u, z=1u;
volatile unsigned int v=1u;
/*...*/
x=v+z/v*y;
/*...*/
}