轉帖|實施案例|編輯:鄭恭琳|2020-07-21 14:48:51.083|閱讀 122 次
概述:編碼規則幫助您提高代碼質量,生成一致代碼,防止易錯編碼風格。為克服嚴峻的軟件開發挑戰并同時減少開發成本,軟件工程領域已經形成了自己的規則慣例,如需求工程分析、設計技術、制程開發,等等。許多規則慣例都應用于開發的實際執行階段,如編碼規則、代碼重構、代碼檢查、靜態分析。其中,編碼規則是基礎,它能夠很好地提高代碼可靠性,幫助不同的開發人員都生成一致的代碼,并防止易出錯編碼方式的出現。 三星電子重點著眼于通過定義并強制執行內部編碼規則來提高代碼質量。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關鏈接:
編碼規則幫助您提高代碼質量,生成一致代碼,防止易錯編碼風格。Robert Buckley對MISRA-C和編碼規則添加了一個注釋。本文作者JunHo和YoonKyu是三星電子軟件實驗室的工程師。
為克服嚴峻的軟件開發挑戰并同時減少開發成本,軟件工程領域已經形成了自己的規則慣例,如需求工程分析、設計技術、制程開發,等等。許多規則慣例都應用于開發的實際執行階段,如編碼規則、代碼重構、代碼檢查、靜態分析。其中,編碼規則是基礎,它能夠很好地提高代碼可靠性,幫助不同的開發人員都生成一致的代碼,并防止易出錯編碼方式的出現。
三星電子重點著眼于通過定義并強制執行內部編碼規則來提高代碼質量。我們QA部門使用了一個編碼標準一致性檢查器來實現這個目的,但我們并沒有規范全部地將這個初始檢查工具應用到我們的軟件開發過程中去。因為這個工具功能不強,所以我們只是在最后的審核階段才偶爾用一下它。因此我們只看到了它對代碼質量的提高起到了一丁點兒的作用。
最近,我們評估了Parasoft的C++TEST,并應用它到我們正在進行的開發項目“MOBILE”中。在本文中,我們將從中學習到的經驗和大家一起分享。在本文中,一個“編碼規則條目”是指一個在公司編碼規則和一致性文檔中描述的總的描述條,一個“編碼規則”(或“規則”)是指一個在自動化編碼規則工具中制訂的具體的編碼規則。
三星電子是一個主要的消費電子公司。盡管三星以主營硬件起家,軟件也迅速成為了我們一個主要的關注中心,正如大多數其他的消費電子廠商一樣。這個“MOBILE”項目是三星的一個電子C/C++開發項目,它是要開發出一個用于移動設備的可重用、可擴展的面向對象的軟件框架。我們的QA部門是一個獨立出來專門測試三星電子開發出來的軟件的。我們投入了相當多的時間來評估自動化工具,以求能最大地減少重復的工作量。
這個MOBILE項目使用一套源于總的三星編碼規則并針對這個項目特別指定的編碼規則。這套MOBILE項目規則可以通過改變語言變量和其他開發約束條件來進行改寫。比如,在MOBILE項目中的一些編譯器不支持對異常情況的處理。因此,當一個對象的構造器被調用的時候,不可能偵測到資源分配失敗。為解決這個問題,我們在 MOBILE 項目中采用了大家熟知的 two-phase object construction(二階段對象構造)技術(在 MOBILE 項目編碼規則中有描述):將一個對象的初始化分為對象分配階段和資源分配階段,以通過一個值的方式返回異常情況(見代碼清單 1)。
class ResourceManager { ResourceManager(); // allocate only object result Construct(); // allocate resources // 'result' contains error code }; int main() { // Two phase construction ResourceManager aObject; if (aObject.Construct() == FAIL) printf("Resource allocation is failed"); }
代碼清單 1
另外,這個MOBILE項目需要對編碼規則進行嚴格恪守。這個項目主要目標是建成一個軟件框架給其他開發人員使用;它必須是一致的、組織良好的,以使得軟件開發能夠很好地在這個框架上進行。越多的項目涉及進來,就越需要一個自動化的工具。這就是為什么MOBILE項目要采用一個編碼規則檢察器。
Parasoft的C++TEST(www.parasoft.com)提供了自動的C/C++單元測試,和自動化的編碼規則檢查。我們選擇 C++TEST作為我們的編碼規則檢查器,是因為它對于我們的大多數考慮來說是最有效的解決方案。
C++TEST 的一個明顯的特點就是它的基于圖形化界面的規則。如圖 1 顯示了對規則“每個全程變量必須進行初始化”的圖形化界面規則描述,在分析源代碼時,每當發現一個“全程變量”,這條規則便會評估邏輯組件。如果以下條件中的任何不相符合,程序就會報告有一個代碼違規:
圖 1: Parasoft C++test中基于圖形化界面的編碼規則
圖形化界面簡化了規則創建。大多數的C++代碼檢查器在創建規則時需要編寫腳本;這有一定的難度,并要求更多的C++編程知識。
因為現有的條件是圖形化顯示的,所以基本圖形化界面的規則能被容易地理解和執行。通過基于圖形化界面的規則可以有更好的可擴展性,因為通過圖形化界面只有預定義的節點和條件可以選擇。
我們的選擇標準包括產品使用特點,但不是特點的細節(規則選擇、規則執行、可量測性)。我們通過以下途徑來建立這些標準:以前的使用編碼規則檢查器的經驗,項目開發部門的反饋,產品評估報告。
能很靈活地修改規則:大多數編碼規則檢查器包括預執行的規格。擁有內含的規則可以減少規則執行的工作量。但是這些規則通常并不完全符合我們的編碼風格。而且,因為大多規則中是簡單地執行,不實的報錯是常見的事,因而使得結果不具可靠性。我們需要一個簡單的方法來自定義規則以排除異常情況,添加新的規則或者修改已存在的規則。類似于LINT的工具可以檢查一些編碼規則項,但缺少規則自定義的特點。盡管有些檢查器也能為規則自定義提供參數修改,但我需要更多的靈活性來修改詳細規則。
能在不同的級別上報告編碼規則的遵守程度:許多編碼規則檢查器支持文件級別的報告。然而,出于管理目的,文件包級和項目級的報告成為管理者們所希望有的。比如,要項目經理經常希望按文件包或項目來瀏覽編碼規則違規以編碼規則違規的趨勢和對編碼規則違規校正的優先級別,特別是在項目工期快要到了的時候。
能與開發環境相集成:許多規則違規能被很容易地校正。比如,像“使用 TAB 而不是空格進行縮進”之類的違規可以通過簡單地用TAB替換空格就可以校正。在這樣的情形中,有一個可以直接訪問違規源代碼(通過與開發環境緊密集成)的編碼規則檢查器,就可以非常有效地減少校正所需要的時間。
另外,當一個工程向前推進的時候,它將所含更多的文件和更的"include/directive"設定。如果檢查器不在IDE內運行,那么檢查器就要通過導入或同步IDE項目文件(如MAKEFILES,DSP/DSW文件等)來創建工程文件。
能為 C/C++創建統一的規則:我們的主要的編程語言,C和C++,有一個相似的結構(除了C++具有更多的基于對象的和類屬性編程)。在兩種語言上為相同的項維護兩種不同的規則將需要額外的資源。
能夠識別語言變量:相比C,C++的歷史比較短。編譯器提供商們在ISO C/C++發布以前產出了他們自己人的 C++編譯器,并且研究顯示,許多 C++的實際應用并不能很好地支持 C++ ISO 標準(//www.ddj.com/184405483)。因為編碼規則檢查器經常分析源代碼,所以能識別語言變量就顯得非常重要了。
能檢查未經預編譯的頭文件:一些編碼規則檢查器缺少對頭文件的直接檢查,取而代之的是,在頭文件中的代碼違規,是通過檢查在預編譯執行的文件中的頭文件進行間接地報告。在這種情況下,一些代碼違規被忽略了,如在頭文件中與預處理程序指令和注釋相關代碼違規,這里通常包含一些被其他開發人員使用的重要信息。所以,直接對頭文件的檢查是一個我們所希望的功能。
應用一個編碼規則檢查器可以減少在應用中的編碼標準違規。然而,偵測和消除的違規數量取決于目標工程的特點和編碼規則的質量。我們發現每個工程都有其相似的整體傾向,但同時又有影響編碼規則檢查的不同細節。因些,得出來的結果應該被看成是一個趨勢而不是一個確定的樣式。
直接的利益是指減少違規數量是如何提高代碼質量的。
非直接利益是指其他不曾預料到的帶給開發人員的好處。
圖 2 顯示了編碼違規數量的總體趨勢。為消除規則不斷發展帶來的影響,我們使用最新的規則來進行所有的檢查。在一個從10月4日到1月5日間相對穩定的違規數量之后,在2月5日有一個大約1/8的違規減少。從2月5日到3月5日間,有一個不希望有的違規增加,但這是可以接受的,因為目標項目仍在繼續向前推進。
圖 2:總的違規數量/每千行代碼
圖 3 顯示了違規校正對只對當前模塊有影響的違規數量。從采用檢查器之日起,違規數量減少了6.6個百分比。這個數量沒有包括注釋規則——這通常不會有大的變化影響但確實是需要重要的進行變更的工作。
圖 3:小變化違規數量/每千行代碼
圖 4 顯示了校正不只影響當前模塊的違規數量。從引入檢查器以來,違規減少了19.6個百分點。
圖 4:有大的改變影響的違規的數量/每千行代碼
代碼規則檢查給我們帶來的一個意外收獲,就是它對開發人員的教育和知識能力提升。新的開發人員,甚至是一些有經驗的開發人員,在開始的時候不大理解一些編碼規則項的意義和重要性。比如,編碼規則項“最好進行初始化而不是分配”是被認為是一個有效的方法來初始化一個構造函數中的成員變量(可參考:《Effective C++》,作者:Scott Meyers,Addison-Wesley,1992)。一些開發人員不理解為什么在一個構造函數的列表中對成員進行初始化要比在構造函數體中對成員分配初始化值要更好。他們在查看檢查器的檢查結果時討論這些問題。這就最終幫助開發人員完全理解了 C++的特點,并且也展示了編碼規則檢查是如何幫助開發人員,使他們從犯錯中進行學習成長的。
另一個間接帶來的好處就是去除了那些不切實際的編碼規則項。當我們應用編碼規則一項目MOBILE中去的時候,我們發現大多數開發人員并不遵守這條規則即“每行不要80格”,這條規則的產生是因為有些老的開發環境是80格顯示。我們檢查了我們的開發環境并得出結論:在我們的條件下,這種有限制的開發環境很少使用,我們建議一行使用更長的格。”所有我們將一行的格數限制從80格改到150格。這種編碼規則修改也可以提高開發人員對遵守編碼規則的接受程度。
直到最近以前,我們的檢查還只是QA部門在工程級別上檢查是否遵守編碼規則。這對于追蹤缺陷傾向和維護一套規則是有效果的。但是會有一些缺點。
首先,報告的違規來源并不總是開發環境中的那段代碼。開發人員通常并不在一個集中的源碼庫中操作,他們在自己的區域進行書寫和修改代碼,然后復制或check-in源碼到集中的代碼庫中。如果開發源碼和QA測試的代碼不一樣,那么開發人員要識別和修改報告違規的來源就比較困難了。
再者,開發人員希望立即能夠驗證到對于違規的校正已經消除了存在的問題。
基于這些原因,我們決定要讓開發人員和QA一樣可以運行編碼規則檢查工具。
那些不認真遵守規則的開發人員會產生很多有違規的代碼,并且也通常不會去校正這些代碼違規。這是尤其會產生與識別或設計相關的違規問題,這樣會使得在以后的開發階段來校正這些錯誤非常困難,因為那時進行這樣的校正會有一個較大的,整個工程范圍的影響。所以我們推薦將編碼規則檢查從早期的編碼階段就開始,這樣違規代碼就能在傳出模塊之前就得到校正。
為什么我們以前的工具沒能在編碼規則檢查上發揮效應的也是因為在整個組織級別上缺乏對規則的維護。
在一套初始規則建立之后,規則應該得到不斷的修改定義,因為某些規則也許不適用于特定的項目,開發風格會根據開發的領域不同而會有改變。一套規則應在項目不斷往前推進的過程中根據項目的具體操作而進行不斷的維護更新。
自動的編碼規則檢查是對代碼走查的一個補充。在我們的開發過程中,代碼走查是強制的,因為這樣可以有效地找出開發人員的邏輯錯誤和失誤。然而,開發人員也會因為工期太緊的壓力跳過代碼走查。根據我們的經驗和研究顯示,一些開發人員很容易被一些編碼風格問題弄得很頭痛,并在代碼走查的過程中花很多工夫到這個上面(參見:D. Kelly 和 T. Shepard 編寫的"Qualitative Observations from SoftwareCode Inspection Experiments"一書; CASCON, 2002),從而,一些開發人員將代碼走查看作是一件耗時卻收效甚微的工作,并不跳過這一步。這種情形可以通過在代碼走查之前使用自動化的代碼規則檢查來消除代碼違規的方法來進行避免。這樣的話,在代碼走查的時候我們就能將精力集中在發現邏輯錯誤和嚴重錯誤上來。而且,自動化的檢查只能涉及到我們編碼規則項中的大約 50%(一些規則項用自動化工具具體執行起來非常復雜),所以代碼走查需要用來檢查剩余的規則項。
我們應用 C++TEST 到了我們幾個項目中并在每個項目中都取得了很好代碼質量提高效果。我們準備將其應用到更多的項目中去,用其分析代碼的質量。
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn