相信不少初學者在閱讀一些開源的C語言項目時,都會看到 assert 關鍵字,那么它有什么用呢,又有哪些好處呢?
assert 關鍵字,什么時候使用它?
C語言中的 assert() 方法可以診斷程序 bug,使用之前應該包含
void assert(int expression);
參數 expression 可以是任意C語言表達式。如果表達式的計算結果為真,assert() 不執行任何操作,反之,如果表達式的計算結果為假,assert() 將在 stderr 上顯示錯誤信息并且終止程序運行。
assert() 一般用于跟蹤C語言程序的運行時(與編譯時不同)錯誤,一般這樣的錯誤不是語法錯誤,所以能夠編譯通過,但是最終得到的C語言程序在執行時,可能會給出不預期的錯誤結果。
可能會給出不預期的錯誤結果
例如,某段分析財務信息的C語言程序出錯了,可能是因為程序中的利率變量 interest_rate 為負導致的,利率是不可能為負的,所以在這樣的一段C語言程序中,可以添加如下語句:
assert(interest_rate>=0);
這樣一旦出現利率為負的情況,assert() 將(以異常方式)終止程序,并給出錯誤信息,這樣一來,我們就可以根據錯誤信息排查代碼了。例如下面這段C語言程序:
#include
#include
int main()
{
double interest_rate = -1;
assert(interest_rate>=0);
printf("won't be here\n");
return 0;
}
可以根據錯誤信息排查代碼
編譯并執行這段C語言代碼,得到如下輸出:
# gcc t.c
# ./a.out
a.out: t.c:7: main: Assertion `interest_rate>=0' failed.
Aborted
顯然,當 interest_rate 為負數時,assert(interest_rate>=0); 將提前(以異常方式)終止程序運行,并給出錯誤的原因。與此同時,后續的C語言代碼將不再有執行機會。
C語言中的 assert() 還有個方便點在于,程序員一旦開發程序完畢,可以在 release 版本程序中關閉 assert() 宏,此時 assert() 宏將不再提供功能,它在程序中的作用等同于一個空格。這一點可以直接查看
顯然,通過 NDEBUG 宏就能控制 assert() 方法的開關了。下面是一個例子:
#include
#define NDEBUG
#include
int main()
{
double interest_rate = -1;
assert(interest_rate>=0);
printf("won't be here\n");
return 0;
}
例子
編譯并執行這段C語言代碼,可以得到如下輸出:
# gcc t.c
# ./a.out
won't be here
可見,assert() 被關閉了。另外,如果 assert() 失敗時,添加一些附加錯誤提示信息,可以使用“短路表達式”(可參考我之前的文章:硬件有短路電路,C語言程序開發中有“短路表達式”你知道嗎?)的技巧:
#include
#include
int main()
{
double interest_rate = -1;
assert(interest_rate>=0 && "interest rate cannot be negtive!" );
printf("won't be here\n");
return 0;
}
可以使用“短路表達式”的技巧
字符串”interest rate cannot be negtive!”必定為真,因此決定 assert() 是否失敗的因素仍然在于 interest_rate>=0 本身,編譯并執行上述C語言代碼,得到如下輸出:
# gcc t.c
# ./a.out
a.out: t.c:7: main: Assertion `interest_rate>=0 && "interest rate cannot be negtive!"' failed.
Aborted
本節主要討論了C語言程序開發中 assert() 宏的使用,它可以在程序開發階段,幫助程序員定位到一些本不應該發生的情況。更加方便的是,一旦程序開發完畢,程序員可以簡單的通過 NDEBUG 宏關閉 assert() 的功能,此時它就等同于一個空格,不會為程序帶來任何性能損失。
點個贊再走吧
歡迎在評論區一起討論,質疑。文章都是手打原創,每天最淺顯的介紹C語言、linux等嵌入式開發,喜歡我的文章就關注一波吧,可以看到最新更新和之前的文章哦。
未經許可,禁止轉載。
推薦閱讀:秦皇島熱線