bool g_debugFlag = false;
int main(int argc, char* argv[]) {
for (int i = 1; i < argc; ++i) {
if (strcmp(argv[i], "--debug=on") == 0) g_debugFlag = true;
}
while (running) {
if (g_debugFlag) { /* 詳細追蹤、資料結構傾印 */ }
// 正常邏輯
}
}
優點:無需重編譯即可在生產環境開啟診斷,配合日誌級別 (Error/Warning/Info/Debug/Trace) 更靈活。
#define TO_STR(x) #x
#define LOG_VAR(x) std::cout << TO_STR(x) << " = " << (x) << std::endl;
// 用法
int timeout = 30;
LOG_VAR(timeout); // 輸出: timeout = 30
進階:配合 `__FILE__`、`__LINE__`、`__func__` (C++11) 實作結構化日誌巨集。
| 特性 | `assert` (標準) | `ASSERT` (MFC/ATL) | `_ASSERTE` (CRT) |
|---|---|---|---|
| 頭檔 | ` | ` | ` |
| 失敗行為 | `abort()` | 彈出對話框 (可進入除錯器) | 輸出至偵錯視窗 (可進入除錯器) |
| Release 關閉 | `NDEBUG` | `NDEBUG` | `NDEBUG` 或 `_DEBUG` 未定義 |
| 建議場景 | 跨平台、標準庫代碼 | MFC/ATL 專案、GUI 應用 | Windows 控制台/服務、混合 CRT |
團隊統一規範:MFC 專案用 `ASSERT`,其他用 `_ASSERTE`,嚴禁混用。
// 傳統巨集版
#define CONTRACT_PRE(cond) _ASSERTE(cond)
#define CONTRACT_POST(cond) _ASSERTE(cond)
#define CONTRACT_INVARIANT(cond) _ASSERTE(cond)
// 現代 GSL 版 (需引入 gsl/gsl_assert)
#include
void Transfer(Account& from, Account& to, Money amount) {
Expects(from.Balance() >= amount); // 前置條件
Expects(&from != &to); // 前置條件
from.Withdraw(amount);
to.Deposit(amount);
Ensures(from.Balance() == old_balance - amount); // 後置條件 (需手工保存 old)
Ensures(to.Balance() == old_balance + amount);
}
GSL 優勢:語意標記化、可被靜態分析工具 (Clang-Tidy `cppcoreguidelines-*`) 識別、Release 版可編譯為無開銷或日誌記錄。
Visual C++ 不只是編譯器,更是一套「編碼→建置→靜態分析→除錯→測試→部署」完整工具鏈。掌握巨集控制、運行期開關、契約斷言、靜態/動態分析整合,才能在 C++ 的自由中建立紀律,交付穩定可靠的軟體。