首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

MFC 斷言機制:ASSERT 宏進行變數/物件合法性檢查

     編輯:關於C語言

MFC 大量使用 `ASSERT` 宏在 Debug 版本執行期檢查前置條件、不變量與後置條件。`ASSERT(expr)` 若 `expr` 為假 (0/NULL),彈出「Assertion Failed」對話框,顯示檔案名、行號與運算式,提供中斷/繼續/忽略選項。本文解析 `ASSERT` 原理、MFC 內部使用範例與正確使用姿勢。

ASSERT 宏定義與行為


// 簡化版定義 (afx.h)
#ifdef _DEBUG
#define ASSERT(f) \
    do { if (!(f)) AfxAssertFailedLine(THIS_FILE, __LINE__); } while (0)
#else
#define ASSERT(f) ((void)0)
#endif
  • 僅 Debug 版本生效,Release 完全移除,零開銷
  • `THIS_FILE` 由 `#undef THIS_FILE` + `static char THIS_FILE[] = __FILE__` 定義
  • 失敗時呼叫 `AfxAssertFailedLine` 顯示對話框

MFC 內部使用範例


// CWnd::Attach - 確保尚未附加視窗
BOOL CWnd::Attach(HWND hWndNew) {
    ASSERT(m_hWnd == NULL);  // 只能 Attach 一次
    // ...
}

// CString::AllocBuffer - 長度合法性
void CString::AllocBuffer(int nLen) {
    ASSERT(nLen >= 0);
    ASSERT(nLen <= INT_MAX - 1);
}

// CDocument::AddView - 視圖未關聯文檔、未在列表中
void CDocument::AddView(CView* pView) {
    ASSERT(pView->m_pDocument == NULL);
    ASSERT(m_viewList.Find(pView, NULL) == NULL);
}

斷言失敗對話框資訊

Assertion Failed!
File: d:\proj\mymfc\view.cpp
Line: 123
Expression: pView->m_pDocument == NULL

選項:Retry (中斷進入除錯器)、Ignore (繼續執行)、Abort (終止程式)。

正確使用指南

  1. 檢查「不應該發生」的邏輯錯誤:指標非 NULL、索引在界、狀態機合法轉換
  2. 不要用於預期會發生的錯誤:檔案不存在、網路斷線、使用者輸入無效 → 應用 `if` 判斷並回傳錯誤碼/拋出例外
  3. 副作用禁止:`ASSERT(p = malloc(...))` 錯誤!Release 版不執行分配 → 改用 `VERIFY` (Debug/Release 皆執行表達式,但僅 Debug 檢查結果)
  4. 配合 `VERIFY`:`VERIFY(::SetEvent(hEvent))` 確保 API 呼叫在 Release 也執行

相關宏

宏DebugRelease用途
ASSERT(expr)檢查並中斷無純邏輯檢查
VERIFY(expr)檢查並中斷執行 exprAPI 呼叫、有副作用運算
ASSERT_VALID(pObj)呼叫 pObj->AssertValid()無檢查 CObject 衍生類內部狀態
ASSERT_KINDOF(class, pObj)檢查 pObj 是否 class 類別無執行期型別安全
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved