2008-10-31 93 views

回答

34

斷言是一種明確檢查代碼所作假設的方法,它通過縮小可能出現的問題來幫助您查找大量錯誤。它們通常僅在應用程序的特殊「調試」版本中進行評估,因此它們不會減慢最終發行版本的速度。

比方說,你寫了一個函數,指針作爲參數。你的代碼很可能會假設指針是非NULL的,所以爲什麼不用斷言來顯式檢查呢?具體方法如下:

#include <assert.h> 

void function(int* pointer_arg) 
{ 
    assert(pointer_arg != NULL); 

    ... 
} 

要注意的重要一點是,你斷言表達式必須永遠不會有副作用,因爲它們不會出現在發佈版本。所以千萬不要這樣做:

assert(a++ == 5); 

有些人還喜歡在他們的斷言中增加一點信息來幫助給他們意義。既然字符串總是evaulates爲true,你可以這樣寫:

assert((a == 5) && "a has the wrong value!!"); 
+0

我還沒有看到與字符串之前。真正有用! – 2008-10-31 11:36:26

6

斷言是布爾表達式,通常應該是true。

他們用來確保你所期望的也是發生了什麼。

void some_function(int age) 
{ 
    assert(age > 0); 
} 

你寫的函數來處理年齡,你也「知道」爲確保您總是傳遞明智的參數,然後使用斷言。這就像說:「我知道這永遠不會出錯,但如果真的出現了,我想知道」,因爲每個人都會犯錯誤。

因此,它不是檢查明智的用戶輸入,如果有情況出現問題,請不要使用斷言。做真正的檢查並處理錯誤。

斷言通常只用於調試版本,因此不要將代碼與副作用置於斷言中。

1

斷言是您添加到您的程序,導致程序立即停止,如果條件滿足,並顯示一條錯誤消息。您通常將它們用於您認爲在您的代碼中永遠不會發生的事情。

0

這裏是一個什麼樣的斷言和here是一些示例代碼definition。簡而言之,斷言是開發人員在任何給定點測試他(或她)對代碼狀態假設的一種方式。例如,如果你在做下面的代碼: - 這mypointer永遠不會調用之前NULL

mypointer->myfunct(); 

你可能想斷言,mypointer,因爲這是你的假設是不爲NULL。

2

斷言是允許您測試程序中可能存在的任何假設的語句。這對記錄程序邏輯(前置條件和後置條件)特別有用。失敗的斷言通常會引發運行時錯誤,並且表明某個程序非常錯誤 - 您的斷言失敗,因爲您認爲事實並非如此。通常的原因是:函數邏輯中存在缺陷,或者函數的調用者傳遞了錯誤的數據。

6

斷言用於驗證設計假設,通常根據輸入參數和返回結果進行驗證。例如

// Given customer and product details for a sale, generate an invoice 

Invoice ProcessOrder(Customer Cust,Product Prod) 
{ 
    assert(IsValid(Cust)); 
    assert(IsValid(Prod); 
' 
' 
' 
    assert(IsValid(RetInvoice)) 
    return(RetInvoice); 

} 

斷言語句不是代碼運行所必需的,但它們檢查輸入和輸出的有效性。如果輸入無效,則調用函數中存在錯誤。如果輸入有效且輸出無效,則此代碼中存在錯誤。請參閱design by contract以瞭解此斷言使用的更多細節。

編輯:正如在其他文章中指出的,斷言的默認實現不包含在發佈運行時。包括我自己在內的很多人都會使用的一種常見做法是將其替換爲發佈版本中包含的版本,但只能在診斷模式下調用。這可以通過完全斷言檢查對發佈版本進行適當的迴歸測試。我的版本如下;

extern void _my_assert(void *, void *, unsigned); 

#define myassert(exp)        \ 
{             \ 
    if (InDiagnostics)        \ 
     if (!(exp))        \ 
      _my_assert(#exp, __FILE__, __LINE__); \ 
}             \ 

這種技術有一個很小的運行時間開銷,但它使跟蹤任何使它進入字段更容易的錯誤。

3

使用斷言來檢查「不能發生」的情況。

典型用法:檢查函數頂部的無效/不可能參數。

很少見過,但仍然有用:循環不變量和後置條件。

1

這並沒有解決斷言設施,已經從早期的ç天回落到我們,但你也應該知道Boost StaticAssert功能,在您的項目可以使用加速事件。

標準C/C++斷言在運行時工作。 Boost StaticAssert工具使您可以在編譯時創建一些類的斷言,甚至更早地捕獲邏輯錯誤等。

相關問題