前不久看到一文章,說用assert的時候不要把非法情形和錯誤情形混淆了,錯誤始終是要處理的.
然后我review自己最近寫的代碼,愣是沒有弄明白什么是非法什么是錯誤,難道錯誤不是非法么,非法不是錯誤么?
我本身用assert是相當頻繁和隨意的,但是經過這么一看,反而覺得原來那些assert的代碼都要改成錯誤處理了...
花非花,霧非霧.
經過思考與實踐,最終確定了規則.
非法情形,大部分你覺得有問題的地方,需要約束的地方,都可以認為可能存在非法情形.比如指針有效性,字符串長度,數值范圍等等.更抽象的說,非法情形存在于動作開始執行前的狀態中.
相對之,錯誤就是動作執行之后的結果,錯誤是針對執行結果的.
詳細而言,當調用一個函數,進入函數體的時候,就進入了一個非法情形出現點,在這里,在執行任何具體的計算和動作之前,面對參數還有其他狀態,你嗅到的任何東西都可以說是非法情形.然后函數開始執行,這里面所出現的任何(大多數)失敗都是一種錯誤,需要進行處理.
需要著重強調的是,函數的執行結果(返回值)絕對是一種錯誤(如果返回值是那個意思的話),而不是非法狀態.(考慮一種計算函數,它的返回結果限制在某個范圍內,這是非法狀態還是錯誤呢?我認為還是錯誤,雖然有些像非法狀態,要進行更嚴格的處理和提示).
我極度強調在函數執行前確認非法狀態,而不是當成錯誤處理(通常這種處理都是默默的,不透明的,不像assert那樣囂張-_-|||).因為我們寫函數(接口)的目的,是希望能被正確的調用,而不是胡亂(導致局部或者整體狀態混亂)的使用(為此我們居然要將assert寫成錯誤處理的形式,以容忍各種白癡的調用行為).
但是有一些情形,在不得以的情況下,比如一個函數,要assert某個指針是有效的,然后才能執行某些動作,但是隨后的執行狀況是,極度可能在那個指針無效的時候卻仍然不可避免的調用該函數,那么你就把assert簡單的用if替換掉就是了,沒什么難的.但是,第一次寫下那個函數的時候,嚇你一跳的assert永遠是不二的選擇,如果你直接就用了if之類的錯誤處理,后面出什么狀況就不是那么顯眼了.
正確的濫用assert吧,至少我是這么做的.
posted on 2006-07-15 18:35
LOGOS 閱讀(2826)
評論(9) 編輯 收藏 引用