1、断言
断言(assertion)是一种编程中常用的手段。在通常情况下,断言就是将一个返回值总是需要为真的判断表达式放在语句中,用于排除在设计的逻辑上不应该产生的情况。
比如:一个函数总需要输入在一定的范围内的参数,那么程序员就可以对该参数使用断言,以迫使在该参数发生异常的时候程序退出,从而避免程序陷入逻辑的混乱。
从一些意义上讲,断言并不是正常程序所必需的,不过对于程序调试来说,通常断言能够帮助程序开发者快速定位那些违反了某些前提条件的程序错误。
如果我们要在 C++ 程序中使用断言,需要在程序中包含头文件 <cassert> 或 <assert.h>,头文件中为我们提供了 assert 宏,用于在运行时进行断言。举例说明:
#include <iostream>
#include <cassert>
// 定义一个自定义函数
float GetResult(const float fDividend, const float fDivisor)
{
// 通过断言判断数组大小是否大于0
assert(fDivisor != 0); // 必须大于0, 否则程序中断
return fDividend / fDivisor;
}
int main()
{
auto fNum = GetResult(10, 0);
std::cout << "结果:fNum = " << fNum;
}
在上面我们定义一个函数,用于求一个除法式子结果,函数GetResult对参数fDivisor进行断言,要求fDivisor的值不等于0,而main函数中对GetResult的使用没有满足此条件,运行时报错,结果如下:
Assertion failed: fDivisor > 0, file C:\xxx\xxx.cpp, line 8
2、静态断言
在上面的例子中我们使用了断言 assert。但 assert 是一个运行时断言,也就是说它只有在程序运行时才能起作用 。有时候我们希望在编译时能做一些断言,使用静态断言 static_assert能达到此目的。
静态断言 static_assert,所谓静态就是在编译时就能够进行检查的断言,使用时不需要引用头文件。静态断言的另一个好处是,可以自定义违反断言时的错误提示信息。静态断言使用起来非常简单,它接收两个参数:
- 参数1:返回bool类型的断言表达式
- 参数2:警告信息,通常是一段字符串,在违反断言时给出提示
举例:在64位Linux下进行测试,使用静态断言验证系统是否是32位:
// static_assert.cpp
#include <iostream>
using namespace std;
int main()
{
static_assert(sizeof(long) == 4, "错误, 不是32位平台...");
cout << "64bit Linux 指针大小: " << sizeof(char*) << endl;
cout << "64bit Linux long 大小: " << sizeof(long) <<endl;
return 0;
}
输入命令:
g++ static_assert.cpp -std=c++11
结果:
static_assert.cpp: In function ‘int main()’:
static_assert.cpp:7:32: error: static assertion failed: 错误, 不是32位平台...
7 | static_assert(sizeof(long) == 4, "错误, 不是32位平台...");
由于使用的 Linux 是 64 位的,因此在编译阶段静态断言检测条件失败,提示的错误信息就是我们给静态断言指定的第二个参数对应的那个字符串。
如果程序员需要的只是运行时的检查,那么还是应该使用assert宏。