2010-04-15 21 views
8

另外,它是如何比較拋出異常時出現問題?VERIFY(...)是C++編碼的良好實踐嗎?

+2

ERR ..什麼是VERIFY()?它不在C++標準庫中......你的意思是斷言聲明嗎? – 2010-04-15 02:45:06

+0

這似乎是MFC-相關:http://msdn.microsoft.com/en-us/library/fcatwy09(VS.71).aspx – Amber 2010-04-15 02:46:48

+1

我不知道爲什麼標準庫已經斷言(),但無法驗證() – Inverse 2010-04-15 04:25:34

回答

18

VERIFY()有異曲同工之妙的ASSERT()(或標準庫assert()) - 讓你趕上的事情,真的不應該永遠™是發生(即真正的代碼錯誤,什麼,應該發佈之前被固定) 。各種各樣的事情,如果由於某種原因表達是錯誤的,沒有意義繼續,因爲某些事情是可怕的,可怕的錯誤。

這反映在VERIFY()僅在調試模式下進行編譯時以虛假評估停止該程序這一事實 - 在發佈模式下,它是透明的。 VERIFY()ASSERT()之間的區別在於VERIFY()仍然會在釋放模式下評估表達式,但它不會在乎結果 - 而在發佈模式下編譯時ASSERT()會完全從程序中刪除,因此表達式的任何副作用在它內部不會發生。

例外情況對於可能出錯,但可以從中恢復的事情更有用,因爲可以通過程序的其他部分處理異常。

5

在Visual C++中,有兩個用於檢查條件的宏:ASSERTVERIFY

在調試模式下,它們都表現相同:即它們都評估它們的參數,如果結果爲0,它們都會用斷言失敗對話框暫停程序。

區別在於發佈模式。在發佈模式下,ASSERT已完全從程序中刪除:它根本不評估它的表達。另一方面,VERIFY仍然評估表達,它只是忽略了結果。

個人認爲,我的意見是,如果檢查在調試模式下是有價值的,那麼它在發佈模式中仍然很有價值,你可能不應該使用它們中的任何一個。只要進行測試並拋出一個異常(或者使用在調試模式下擴展爲assert()的自定義宏,以及在發佈模式下的異常)。

+1

一個有用的區別是,如果您有需要一段時間才能運行的「nitpicky」測試,則可以將它們放在'ASSERT()'中,然後不用擔心釋放模式下的性能損失。 – Amber 2010-04-15 02:55:15

+0

您對opion的調試模式檢查是否處於發佈模式也在這裏得到很好的支持! – Cameron 2014-02-07 22:44:08

6

這個問題看起來很簡單,但隱藏了一個巨大的主題:處理錯誤。

Summarilly我想說斷言驗證是工具研究與開發過程中使用異常和系統調用錯誤檢查是生產代碼的正常部分處理運行時錯誤

  • 斷言(它適用於維護和驗證)大多在防守編程風格的工具。他們的主要目標是防止永遠不會發生的情況,程序員不知道如果發生該怎麼辦。通常它用於檢查編程錯誤。在調試程序時發生不可能的事情時,通常要儘可能快地檢測並報告它。它將簡化錯誤糾正。您可以在某些情況下使用它,或者通常用於檢查交換機的分支是否永遠不會被捕獲。

    我主要在處理第三方代碼時使用斷言,這些代碼的行爲我不確定。爲了檢查我自己的代碼在開發中的行爲,我通常更喜歡單元測試。

    現在,正如施羅寧丁教給我們的,mesures改變了一切。當啓用斷言並且在釋放模式下停止工作時,您可能有時會有代碼在調試模式下工作。它通常是斷言條件中隱藏的錯誤的症狀(副作用,對時間敏感的代碼)。驗證儘量減少這種風險,但可以認爲這是一種不好的做法,就像清掃地毯後面的灰塵一樣。

    您還可以使用驗證快速編碼作爲scafolding的地方,你還沒有設置真正的錯誤處理。我不相信你應該讓任何生產代碼驗證。

  • 例外是程序控制流的正常部分。它們通常用於處理錯誤,但這不是它們唯一可能的用法(那些使用Python等其他語言的用戶會知道我在說什麼)。它們也不應被視爲唯一的錯誤管理工具。如果未包含在C++知識庫中,則系統調用仍會返回錯誤代碼,而不是引發異常。

    作爲一個經驗法則應該由能夠合理處理它們的最近的對象捕捉異常。

    並非所有的例外都應被視爲致命錯誤並停止計劃。想象一下,你正在處理一個網絡視頻流庫,通過異常返回錯誤情況。它會拋出一個異常警告,說明一個幀被丟棄,你通常不想停止該程序,而只是準備好下一幀。

    即使做的最好的事情就是停止你不應該讓異常爲你做它(你必須使用斷言在生產代碼,目的甚至更少的原因)的計劃。爲此,應該總是存在一個頂級異常處理程序,它會顯式調用exit()之類的。不這樣做只是表明程序員不關心可能發生的事情,可能沒有想到它。

+0

好點,+1 ... – sevaxx 2010-04-17 05:15:27

+3

爲'未捕獲的異常'放置一個頂級異常處理程序的缺點是,如果發生未捕獲的異常,堆棧就會銷燬到頂級處理程序;然後它會做一些完全不感興趣的事情,比如說發生了什麼異常,然後像你說的那樣,退出程序。如果不完全處理它,則調試器有機會在std :: terminate處終止程序,並使整個執行堆棧可用且可檢查。 – rvalue 2011-10-10 23:47:17