C++代碼評審(Code Review)等級標准
0
前言
記錄的問題都是來源於平常C++編碼過程之中常見或基礎的缺陷。
只是由個人整理而成的標准,用於平常代碼編寫中的“掃雷”,沒有權威性,現應用於我的開發團隊。
后續的補充完善還是一個漫長的過程。
程序員要善於記錄和總結,這樣才能成長和提升。
1
簡介
代碼評審定義:通過閱讀代碼檢查代碼缺陷的質量保證過程。
代碼評審內容:編程規范,重構方法,架構設計,性能安全,日志,可讀性,擴展性。。。
代碼評審好處:及早發現編碼缺陷,分析編碼缺陷,提升代碼質量,提高編碼水平,促進團隊合作。。。
代碼評審形式:代碼走讀,代碼講解,結對編程,交叉評審,專家評審,評審會議(只發現問題,不在會議上討論和解決問題)。。。
2
等級標准
一般分三種等級:
嚴重:會引起系統死機,程序崩潰,功能不可用,導致嚴重后果的問題。
一般:會引起功能部分不可用,設計缺陷,運行效率的問題。
提示:會引起代碼可讀性差,違反編程規范的問題。
3
嚴重等級及問題示例
1) 問題類型:操作空指針 問題示例: CTestClass *p = NULL; p->GetName();//操作空指針
2) 問題類型:操作非法指針 問題示例: char *p = new char[100]; delete p; memcpy(p,"你好");//操作非法指針
3) 問題類型:指針未判斷為空 問題示例: if(NULL == P);//要有指針判斷為空
4) 問題類型:野指針 問題示例: new和delete應成對出現 malloc和free應成對出現
5) 問題類型:死循環 問題示例: while(...) { i++;//i++保證不會死循環 };
6) 問題類型:邏輯錯誤 問題示例: 指代碼邏輯混亂或相關
7) 問題類型:資源泄漏 問題示例: CDialog::Create要有CWnd::DestroyWindow來釋放 CreateIcon、GetIcon要有DestroyIcon來釋放 CBitmap LoadImage要有DeleteObject來釋放
8) 問題類型:數組越界 問題示例: char szArray[MAX]; printf("%c",szArray[MAX]);//數組越界
9) 問題類型:循環體內改寫循環變量 問題示例: for(int i=0;i<MAX;i++) { i = 100;//循環體內改寫循環變量 }
10) 問題類型:IO操作、數據庫操作資源未釋放 問題示例: 打開的操作必須要關閉,open()和close()操作應成對出現。
11) 問題類型:判斷無符號數是否小於0 問題示例: UInt iLen = MAX; if(iLen < 0)//判斷無符號數是否小於0 { ... }
12) 問題類型:內存拷貝忽略結尾標志'\0' 問題示例: char *s = "aaaa"; char a[4]; memcpy(a,s,4);//內存拷貝忽略結尾標志'\0'
13) 問題類型:函數內部修改形參 問題示例: string GetName(int iID) { iID = 100;//函數內部修改形參 ... }
14) 問題類型:new數組,delete無[] 問題示例: char *a = new char[100]; ... delete a;//new數組,delete無[]
15) 問題類型:局部變量和局部變量、函數參數、全局變量重名 16) 問題類型:對象不能用memset初始化 17) 問題類型:多線程資源未做互斥處理 18) 問題類型:代碼圈復雜度不能高於14 19) 問題類型:函數代碼嵌套級數不能超過6 20) 問題類型:調試或日志信息中不能有敏感信息
4
一般等級及問題示例
1) 問題類型:變量未初始化 問題示例: char *a;//變量未初始化 char b[100]; strcpy(b,a);
2) 問題類型:函數入參未進行校驗 問題示例: void FunTest(CTestClass *p) { p->Get();//函數入參未進行校驗 }
3) 問題類型:布爾值與非布爾值比較 問題示例: int i = 0; bool flag = true; if(i == flag)//布爾值與非布爾值比較 { ... }
4) 問題類型:浮點數與0比較 問題示例: double dwLen = 0.1; if(0 == dwLen)//浮點數與0比較 { ... }
5) 問題類型:不同數據類型強制比較或賦值 問題示例: long lMax = 32768; short iLen = 0; iLen = lMax;//不同數據類型強制賦值
6) 問題類型:復雜表達式未加括號表示優先級 問題示例: if(i==j&&i==k||i==l||j==k)//復雜表達式未加括號表示優先級 { ... }
7) 問題類型:函數無返回值或返回值不正確 問題示例: bool Fun() { int i = 0; ... return i;//函數返回值不正確 }
8) 問題類型:指針判斷有誤 問題示例: bool Fun(char *p) { if(p)//指針判斷有誤 }
9) 問題類型:變量比較應放在==左邊 問題示例: if(p == NULL)//變量比較應放在==左邊
10) 問題類型:重復代碼 問題示例: 重復代碼要提煉或封裝,一定要重復的應加注釋其重復合理性
5
提示等級及問題示例
1) 問題類型:魔鬼數字 問題示例: for(int i=0;i<1000;i++)//魔鬼數字 { ... }
2) 問題類型:注釋錯誤 問題示例: 注釋有錯別字或語意表達錯誤
3) 問題類型:注釋無效 問題示例: 注釋必須要合理,不多余,不廢話
4)
問題類型:無注釋或注釋量過低
問題示例:
注釋正常應該在30%以上
5) 問題類型:排版或縮進混亂 問題示例: 空行、縮進必須規范(4空格代替tab)
6) 問題類型:冗余代碼 問題示例: 無用注釋或無用代碼
7) 問題類型:維護性質代碼無說明 問題示例: 維護性質的代碼要有注釋
8) 問題類型:if、for、while、switch等語句應加{} 問題示例: switch(i) case 1: ... //應加{} break; case 2: ... break;
9) 問題類型:文件總行數不超過2000 10) 問題類型:函數總行數不超過200 11) 問題類型:函數形參不超過5 12) 問題類型:命名不符合編程規范