博主介紹:程序喵大人
- 35- 資深C/C++/Rust/Android/iOS客戶端開發
- 10年大廠工作經驗
- 嵌入式/人工智能/自動駕駛/音視頻/游戲開發入門級選手
- 《C++20高級編程》《C++23高級編程》等多本書籍著譯者
- 更多原創精品文章,首發gzh,見文末
- 👇👇記得訂閱專欄,以防走丟👇👇
😉C++基礎系列專欄
😃C語言基礎系列專欄
🤣C++大佬養成攻略專欄
🤓C++訓練營
👉🏻個人網站
在C/C++
里,assert是一種比較常用的調試策略。
定義
assert
字面意思是斷言,用于判斷是否滿足某個條件,如果不滿足某個條件,則程序會直接崩潰,控制臺上會顯示崩潰所在的文件名和行號。
看下它的使用:
#include <assert.h>
#include <stdio.h>void func(int a) {assert(a > 0);printf("%d", a);
}int main() { func(-1); }
示例中我用assert
來表示函數func
的輸入一定要>0。
我如果輸入了-1
,程序運行時會在assert
處crash
,同時提供了報錯的詳細:
a.out: test.cc:5: void func(int): Assertion `a > 0' failed.Aborted
注意事項:
我們一定在assert
處只做判斷,不要添加任何功能邏輯,因為assert只在debug模式下有作用,release
模式下,assert
這行代碼會自動跳過去,會自動被忽略。
assert(++i > 0);
這種改變了i狀態的assert
代碼千萬不要寫,因為會導致debug模式和release模式下的行為不一致。
什么時候使用assert
?
期望某塊邏輯一定要滿足某個前置條件,如果不滿足就要crash
,這方便于我們在debug
模式下調試程序,如果crash
,方便我們進一步修復問題,使其滿足assert
條件。
比如我們要輸出某個字符串,做一次判空其實也是耗費性能的,我們期望傳進來的串一定非空,如果是空,那就直接crash
:
void func(const char* s) {printf("hello %s \n", s);
}
static_assert
上面的assert
是運行時斷言,C++11之后還有個編譯時斷言:static_assert
,用于在編譯時判斷某些條件,如果斷言失敗,則會編譯失敗,用法和assert
類似。
#include <type_traits>
constexpr int k = 120;
int main() { static_assert(k > 200, "k < 200"); }
輸出:
test.cc:8:14: error: static_assert failed due to requirement 'k > 200' "k < 200"int main() { static_assert(k > 200, "k < 200"); }
^ ~~~~~~~1 error generated
static_assert
后面可以跟著一個字符串,在斷言失敗時,會在控制臺輸出此字符串,方便提示我們相關信息。
練習
static_assert
還有很多作用,比如可以判斷某個類是否有默認構造函數,某個函數是否是noexcept
等,可以自己嘗試一下。