以C++語言標准委員會現主席Herb Sutter老兄以及他編寫的Exceptional系列已出版的包括:《Exceptional C++》、《More Exceptional C++》、以及《Exceptional C++ Style》)為甚。。
主動調試和契約編程相輔相成,共同保證軟件開發的質量。契約編程相當於經濟生活中簽訂的各種合同,而主動調試相當於某方不遵守合同時采取的法律懲罰措施。
各種開發語言和開發工具都提供這些調試語句,標准C++提供了assert函數,MFC提供了ASSERT調試宏幫助我們進行主動調試,在實際工作中,建議統一使用MFC的ASSERT調試宏。
參數檢查
對於編寫的函數,除了明確的指定契約外,在函數開始處應該對傳入的參數進行檢查,確保非法參數傳入時立即報告錯誤信息。例如:
- BOOL GetPathItem ( int i , LPTSTR szItem , int iLen )
- {
- ASSERT ( i > 0 ) ;
- ASSERT ( NULL != szItem ) ;
- ASSERT ( ( iLen > 0 ) && ( iLen < MAX_PATH ) ) ;
- ASSERT ( FALSE == IsBadWriteStringPtr ( szItem , iLen ) ) ;
- }
這樣的檢查只能夠排除指針為空的情況,但是如果指針指向的是非法地址,或者指針指向的對象並不是我們需要的類型,上面的例子就沒有辦法檢查出來,而是統統認為是正確的。完整的檢查應該如下:
- // An example of checking only a part of the error condition
- BOOL EnumerateListItems ( PFNELCALLBACK pfnCallback )
- {
- ASSERT ( NULL != pfnCallback ) ;
- }
恰當地在代碼中使用ASSERT,對bug檢測和提高調試效率有極大的幫助,下面舉個簡單的例子加以說明。
- switch( nType )
- {
- case GK_ENTITY_POINT:
- // do something
- break;
- case GK_ENTITY_PLINE:
- // do something
- break;
- default:
- ASSERT( 0 );
- }
在上面的例子中,switch語句僅僅處理了GK_ENTITY_POINT和GK_ENTITY_PLINE兩種情況,應該是系統中當時只需要處理這兩種情況,但是如果後期系統需要處理更多的情況,而此時上面這部分代碼又沒有及時更新,或者是因為開發人員一時疏忽遺漏了。
一個可能導致系統錯誤或者崩潰的bug就出現了,而使用ASSERT可以及時地提醒開發人員他的疏忽,盡可能快的消滅這個bug。還有一些情況,在開發人員編寫代碼時,如果能夠確信在某一點出現情況A就是錯誤的,那麼就可以在該處加上ASSERT,排除情況A。
綜上所述,恰當、靈活的使用ASSERT進行主動調試,能夠極大提高程序的穩定性和安全性,減少調試時間,提高工作效率。綜上所述,恰當、靈活的使用ASSERT進行主動調試,能夠極大提高程序的穩定性和安全性,減少調試時間,提高工作效率。