斷言(assert)
斷言(assert)是一種編程中常用的手段坐搔。斷言就是將一個返回值總需要為真的判別式放在語句中,用于排除在設(shè)計的邏輯上不該產(chǎn)生的情況。請看如下代碼:
void assert_test(int i) {
cout << "Before assert, i is " << i << endl;
assert(i > 0);
cout << "After assert." << endl;
}
上述代碼期望函數(shù)的參數(shù)總是大于0,如果小于等于0弓摘,則(i > 0)不成立,當(dāng)傳入?yún)?shù)為-1的時候看到以下結(jié)果:
在C++中痕届,可以使用NDEBUG宏可以禁用assert宏韧献,上述代碼在編譯過程中加入“-DNDEBUG”參數(shù)末患,則執(zhí)行上述代碼結(jié)果如下:
可以看到并未出錯。在用戶使用場景中锤窑,發(fā)送錯誤導(dǎo)致程序退出對用戶來說總是不友好的璧针,在某些錯誤即使發(fā)生也不會影響其他的功能,但在開發(fā)過程中找到錯誤則是必要的果复。所以在Debug版程序中需要使用assert陈莽,而Release版則可以添加-DNDEBUG宏來關(guān)閉assert。
#error
從上述可知assert是在運(yùn)行階段判斷是否有錯誤虽抄,編譯器也為我們提供來在編譯預(yù)處理階段進(jìn)行斷言操作的方法走搁,即#error。請看如下代碼:
#ifndef STATIC_ASSERT_DEMO_H
#error "Please include static_assert_demo head file."
#endif
上述代碼表示迈窟,如果沒有include頭文件“static_assert_demo.h”私植,則不會定義STATIC_ASSERT_DEMO_H宏,則在編譯預(yù)處理階段就會打印#error所示的錯誤车酣,編譯上述代碼結(jié)果如下:
在包含相應(yīng)的頭文件后曲稼,則編譯沒有錯誤。
通過#error湖员,可以結(jié)合#if和#endif贫悄,在預(yù)處理階段進(jìn)行斷言判斷。
靜態(tài)斷言(static_assert)
assert在運(yùn)行時才能起作用娘摔,#errror在預(yù)處理階段起作用窄坦。有時我們希望在編譯過程中做一些斷言,C++11中因此引入了靜態(tài)斷言(static_assert)操作凳寺。
static_assert有兩個參數(shù)鸭津,分別為一個斷言表達(dá)式,一個為警告信息(字符串)肠缨。請看如下代碼:
void static_assert_test() {
static_assert(sizeof(long int) == 4, "The software is not suitable for 64-bit machines.");
}
上述代碼表示如果不在32位機(jī)器(long int長度為4)上編譯逆趋,則會報錯。編譯上述代碼結(jié)果如下:
通過靜態(tài)斷言機(jī)制晒奕,在編譯過程中可以排除代碼中一些隱藏的錯誤闻书。