C語(yǔ)言如何使用斷言避免踩坑
何為斷言
斷言一般是用于檢測(cè)在某個(gè)程序位置程序必須滿(mǎn)足某些條件的宏。一般用的多的可以分兩種種情況:
-
前置條件:在某個(gè)程度點(diǎn)開(kāi)始的地方
-
后置條件:在某段程序執(zhí)行結(jié)束后,一般用于檢測(cè)執(zhí)行結(jié)果
也可以編程者自己定義,比如:
該怎么用
前置條件
比如某一個(gè)函數(shù)代碼:
int func(int size, char *buffer )
{
assert( size <= ALLOWED_SIZE );
assert( format != NULL );
...
}
這個(gè)函數(shù)里,使用了兩次斷言判斷函數(shù)執(zhí)行的前置條件:
- size必須要不大于A(yíng)LLOWED_SIZE,func函數(shù)才真正執(zhí)行其任務(wù)。因此,如果輸入的size超過(guò)1024,func不會(huì)做任何處理。
- buffer傳入的地址必須不是NULL,否則func函數(shù)不會(huì)執(zhí)行。
后置條件
后置條件斷言一般是指判斷函數(shù)的執(zhí)行結(jié)果。比如:
{
int result;
/*中間處理部分更新這個(gè)返回值*/
...
assert( result <= ALLOWED_SIZE );
return result;
}
這樣寫(xiě)表示這個(gè)函數(shù)的返回值永遠(yuǎn)不會(huì)大于A(yíng)LLOWED_SIZE。如果大于了,就證明產(chǎn)生錯(cuò)誤了。
什么時(shí)候用
斷言的最常用和最有效的用途是檢查前置條件——即指定和檢查函數(shù)的輸入條件。兩個(gè)非常常見(jiàn)的用途:
- 指針不是 NULL。
- 索引和邊界范圍值是在設(shè)計(jì)的合理范圍之類(lèi)。
-
如果在程序測(cè)試和調(diào)試期間違反了前置條件,也就是說(shuō)斷言異常了,則調(diào)用包含前置條件的函數(shù)的代碼中存在bug。
-
如果在程序測(cè)試和調(diào)試期間違反了后置條件,則該斷言前面部分代碼可能有bug。
- 程序錯(cuò)誤是一個(gè)bug,永遠(yuǎn)不應(yīng)該發(fā)生。
- 運(yùn)行時(shí)錯(cuò)誤可能在程序執(zhí)行期間的任何時(shí)間發(fā)生。
{
QVector <int> list;
list.append(0);
list.append(1);
qDebug() << list.at(2);
return 0;
}
一運(yùn)行,就會(huì)有這樣的結(jié)果:
assert in File=..\src\main.cpp Line=4
因?yàn)閘ist只有兩個(gè)元素,list.at(2)則是去訪(fǎng)問(wèn)第3個(gè),顯然訪(fǎng)問(wèn)的元素不存在,所以就斷言了。
—— The End ——