Share via


assert宏、 、 _assert_wassert

評估運算式;當結果為 false時,列印診斷資訊並中止程式。

語法

assert(
   expression
);
void _assert(
   char const* message,
   char const* filename,
   unsigned line
);
void _wassert(
   wchar_t const* message,
   wchar_t const* filename,
   unsigned line
);

參數

expression
評估為非零 (true) 或 0 (false) 的純量運算式 (包括指標運算式)。

message
要顯示的訊息。

filename
判斷提示失敗之原始程式檔的名稱。

line
判斷提示失敗之原始程式檔中的行號。

備註

assert 巨集通常可用來找出程式開發期間的邏輯錯誤。 此巨集可在發生未預期的情況時,用來停止程式執行,方法是實作 expression 引數,僅在程式運作異常時評估為 false 。 您可以定義巨集 NDEBUG,在編譯時期關閉判斷提示檢查。 您可以使用命令列選項來關閉 assert 宏,而不需修改原始程式檔 /DNDEBUG 。 您可以在包含 之前 <assert.h> 先使用 #define NDEBUG 指示詞來關閉 assert 原始程式碼中的宏。

當評估為 false (0) 並呼叫 abort 以停止程式執行時 expression ,宏 assert 會列印診斷訊息。 如果 expressiontrue (非零),則不會採取任何動作。 診斷訊息包含失敗的運算式,以及判斷提示失敗之原始程式檔的名稱及其中的行號。

診斷訊息會以寬字元列印 wchar_t 。 因此,即使運算式中有 Unicode 字元,它仍會如預期般運作。

診斷訊息的目的地取決於呼叫常式的應用程式類型。 主控台應用程式會透過 stderr 接收訊息。 在以 Windows 為基礎的應用程式中, assert 呼叫 Windows MessageBox 函式來建立訊息方塊,以顯示包含三個按鈕的訊息: 中止 重試 忽略 。 如果使用者選擇 中止 ,程式會立即中止。 如果使用者選擇 [ 重試 ],則會呼叫偵錯工具,而且如果已啟用 Just-In-Time (JIT) 偵錯,使用者可以偵錯程式。 如果使用者選擇 [忽略 ],程式將會繼續正常執行。 發生錯誤條件時按一下 [ 忽略 ] 可能會導致未定義的行為,因為不符合呼叫程式碼的前置條件。

若要覆寫預設輸出行為,不論應用程式類型為何,請呼叫 _set_error_mode 以在 output-to-stderr 和 display-dialog-box 行為之間進行選取。

在顯示其訊息之後 assert ,它會呼叫 abort ,其會顯示對話方塊,其中包含 [中止 ]、 [重試 ] 和 [忽略 ] 按鈕。 abort 結束程式,因此 [重試 ] 和 [忽略 ] 按鈕不會在呼叫之後 assert 繼續執行程式。 如果 assert 顯示對話方塊, abort 則不會顯示對話方塊。 唯一顯示對話方塊的時間 abortassert 將其輸出傳送至 stderr。

由於上述行為,在偵錯模式中呼叫之後,一律會顯示 assert 對話方塊。 下表會擷取每個按鈕的行為。

錯誤模式 輸出至 stderr (主控台/ _OUT_TO_STDERR 顯示對話方塊 (Windows/ _OUT_TO_MSGBOX
Abort 使用結束代碼 3 立即結束 使用結束代碼 3 立即結束
Retry 在 期間中斷偵錯工具 abort 在 期間中斷偵錯工具 assert
Ignore 完成結束 abort 繼續程式, assert 好像沒有引發 (可能會導致未定義的行為,因為不符合呼叫程式碼的先決條件)

如需 CRT 偵錯的詳細資訊,請參閱 CRT 偵錯技術

_assert_wassert 函式是內部 CRT 函式。 這些函式可協助減少物件檔案中用以支援判斷提示所需的程式碼。 不建議您直接呼叫這些函式。

未定義 時 NDEBUG ,宏 assert 會在 C 執行時間程式庫的版本和偵錯版本中啟用。 定義 時 NDEBUG ,宏可以使用,但不會評估其引數,而且沒有作用。 啟用時, assert 宏會呼叫 _wassert 其實作。 其他判斷提示宏 _ASSERT_ASSERTE_ASSERT_EXPR 也可供使用,但只有在定義宏時 _DEBUG ,以及當它們位於與 C 執行時間程式庫偵錯版本的程式碼中時,才會評估傳遞給它們的運算式。

需求

常式 必要的標頭
assert, _wassert <assert.h>

標頭檔無法使用函 _assert 式的簽章。 只有在未定義宏時 NDEBUG ,才能使用函式的 _wassert 簽章。

範例

在這個程式中, analyze_string 函式使用 assert 巨集來測試幾個與字串和長度相關的條件。 如果任何一個條件失敗,程式會列印訊息,指出失敗的原因。

// crt_assert.c
// compile by using: cl /W4 crt_assert.c
#include <stdio.h>
#include <assert.h>
#include <string.h>

void analyze_string( char *string );   // Prototype

int main( void )
{
   char  test1[] = "abc", *test2 = NULL, test3[] = "";

   printf ( "Analyzing string '%s'\n", test1 ); fflush( stdout );
   analyze_string( test1 );
   printf ( "Analyzing string '%s'\n", test2 ); fflush( stdout );
   analyze_string( test2 );
   printf ( "Analyzing string '%s'\n", test3 ); fflush( stdout );
   analyze_string( test3 );
}

// Tests a string to see if it is NULL,
// empty, or longer than 0 characters.
void analyze_string( char * string )
{
   assert( string != NULL );        // Cannot be NULL
   assert( *string != '\0' );       // Cannot be empty
   assert( strlen( string ) > 2 );  // Length must exceed 2
}

程式會產生以下輸出:

Analyzing string 'abc'
Analyzing string '(null)'
Assertion failed: string != NULL, file crt_assert.c, line 25

判斷提示失敗之後,視作業系統版本和執行時間程式庫而定,您可能會看到訊息方塊,其中包含類似下列內容:

A problem caused the program to stop working correctly. Windows will close the program and notify you if a solution is available.

如果已安裝偵錯工具,請選擇 [偵錯] 按鈕以啟動偵錯工具,或選擇 [關閉程式] 結束。

另請參閱

錯誤處理
進程和環境控制
abort
raise
signal
_ASSERT、、 _ASSERTE_ASSERT_EXPR
_DEBUG