- assert
- error code
- exception
- 用到 STL 或有拋出 exception 的程式,因你無法保證 100%不會有 exception。
- 簡化程式流程的時候,這在預設執行的各 method/function 都是 99.9%正確時可簡化,遇到不能考慮的錯誤時就是那 0.01%。
- 子程式不知怎麼處理此錯誤,可能父程式或父父程式以上(最高為使用者)知道如何處理時。
- 想回傳error code卻不行時。
- 不要在同一 scope throw, catch,這很明顯可以用 if else/switch 來解決,但是很多書上都這樣教。
- 父程式可考慮解決的錯誤可以使用 error code。
while (IsSending) { try { foo->Send(SendData); IsSending=false; foo->Save(SendData); } catch(Exception &e) { ErrorMsg = e.ClassName() + ":" + e.Message; } }還是使用 error code 的方式吧,我無法想像用exception來處理:
while (IsSending) { ErrorCode error_code; error_code=foo->Send(SendData); switch(error_code) { case SEND_OK: IsSending=false; error_code=foo->Save(SendData); switch(error_code) { case SAVE_OK: break; case SAVE_NO_FILE: //Create a new file break; case SAVE_BE_LOCK: //UnLock or throw if can't be UnLock here break; } break; case SEND_NOT_FINISH: //Get left SendData (then Send) break; case SEND_EMPTY: //WaitData or GetData (then Send ) break; case SEND_BE_LOCK: //UnLock(then Send) or throw if can't be UnLock here break; } }好吧寫個參考,用exception來處理:
while (IsSending) { try { foo->Send(SendData); IsSending=false; } catch(Exception &e) { ErrorCode error_code = e.Code; switch(error_code) { case SEND_NOT_FINISH: //Get left SendData (then Send) break; case SEND_EMPTY: //WaitData or GetData (then Send ) break; case SEND_BE_LOCK: //UnLock(then Send) or throw if can't be UnLock here break; } } try { foo->Save(SendData); } catch(Exception &e) { ErrorCode error_code = e.Code; switch(error_code) { case SAVE_NO_FILE: //Create a new file break; case SAVE_BE_LOCK: //UnLock or throw if can't be UnLock here break; } } }嗯有比較簡潔嗎? 或許可以改寫成以下方式:
while (IsSending) { try { foo->Send(SendData); IsSending=false; foo->Save(SendData); } catch(Exception &e) { ErrorCode error_code = e.Code; switch(error_code) { case SEND_NOT_FINISH: //Get left SendData (then Send) break; case SEND_EMPTY: //WaitData or GetData (then Send ) break; case SEND_BE_LOCK: //UnLock(then Send) or throw if can't be UnLock here break; case SAVE_NO_FILE: IsSending=false; //Create a new file break; case SAVE_BE_LOCK: IsSending=false; //UnLock or throw if can't be UnLock here break; } } }雖然在程式上看來較簡潔,但是對於程式流程卻較複雜,隨著程式碼越多,跳到哪裡都不知道了... 其他不使用ex的原因還有影響效能,團隊編程顧慮等。 但使用error code (status code) 也有以下缺點:
- error code是可以被忽略的。
- 無法自動向上上層(父父程式)傳播。必須由上層接力在丟一次。
- 在程式流程中不能集中處理(某些情況是優點)。
- 必須有回傳值或紀錄值。
Next: c++ checked exceptions (Exception specifications)?
根據[C++ coding Standards] 書中第 75 項 Avoid exception specifications , 且在 A Pragmatic Look at Exception Specifications 中的建議 "Never write an exception specification." 所以就不研究了,進階可看 Questions About Exception Specifications。
[Reference]
- Google Forbids Use of Exception in C++
- Exception Handling 新思維
- 關於錯誤訊息及Exception的處理?
- Replace Exception with Test
- Replace Error Code with Exception
- The rationale of programming - I. Exception or Error Code
- return values or exceptions?
- Exception Safety and Exception Specifications: Are They Worth It?
- 關於 C++ Exception