Who's code caught the error, who deal with it?
這是一個很久很久以前就有的 murmur。
在工作上,有時候會聽到這樣的怒吼:「吼~又是你的 assertion 把程式當掉。」可是,細查之後卻又發現,之所以會 assertion failure,是某個應該存在的值不存在,或某件事情在之前就失敗了,於是當程式執行到 assertion 處,一檢查就發現問題,然後把程式當掉。
Assertion 之所以存在,為的就是希望能夠揪出,所有不應該存在的異常情形,是故,assertion 其實應該是多多益善,埋的越多,越有機會揪出程式的不良之處。所以,我很喜歡埋 assertion,凡是無法處理的特殊輸入、必須存在的情境參數,甚至是失敗就等於整個程式根本無法運作的 API 呼叫[1],我都會使用 assertion 以便盡早地把程式當掉,輔助我們揪出錯誤的發生點。
問題是,當 assertion 發生時,總是要有某個人負責去找出問題的成因,而理所當然地,在只有 assertion failure 這條線索的情況下,問題就被丟給寫 assertion 的人。但因為 assertion 通常是用來抓「不是在此處發生的錯誤」,因此產生了這麼一個吊詭:
越認真地(寫程式)使錯誤顯現的人,反而越容易領到爛攤子,必須承擔解決(多半)不是其程式所造成之錯誤的責任。
一般來說,程式設計師比較喜歡寫新程式,而不喜歡維護舊程式,更討厭的就是負責維護不是他寫的舊程式,所以上述的吊詭,等於是在懲罰認真的人,而且是越認真(埋 assertion 炸彈),等著的是越多的爛攤子。
也就是說,可以討論的,應該是 assertion 的標的是否合適,而不是 assertion 是否應該把程式當掉。只要標的合適,當程式當掉時,我們該慶幸,assertion 讓我們發現,程式會當掉,而不是等到移交給客戶後,隱藏的炸彈才一個一個爆發。
- 如
malloc()失敗。 ↩



3 Comments
在 VC 編出來的程式,Assert 不會把程式當掉,而是跳出一個 prompt。而且 assert 只在 debug 模式有用,不應該當成錯誤處理工具,頂多是拿來確保「絕對不可能發生的事」不會發生,而不是拿來擋一些有可能發生的情況。
所以如果在 release 模式下當掉了,而 debug 模式被擋下來,那肯定不是被 assert 當掉的,因為在 release 模式 assert 無作用,而 debug 模式也只是跳出一個 prompt 擋下來。要是有人像你講的那樣吼,只是顯現自己程度不佳而已。
Dear av,
雖然不想這麼說,
在台灣,
程式設計師的平均程度不佳.
"程式設計師比較喜歡寫新程式,而不喜歡維護舊程式,更討厭的就是負責維護不是他寫的舊程式", 啊, 我就在干"更讨厌"的事...
assert 看起来挺丑的..
Post a Comment