C++ 中assert断言函数的基本用法

在咱们的实际开发过程之中,经常会出现一些隐藏得很深的BUG,或者是一些几率性发生的BUG,一般这些BUG在咱们调试的过程当中不会出现很明显的问题,可是若是咱们将其发布,在用户的各类运行环境下,这些程序可能就会露出马脚了。那么,如何让咱们的程序更明显的暴露出问题呢?这种状况下,咱们通常都会使用 assert 断言函数,这是C语言标准库提供的一个函数,也就是说,它的使用与操做系统平台,调试器种类无关。咱们只要学会了它的使用,即可一次使用,到处开花。ios

断言assert原型

void assert(int expression);

assert宏的原型定义在 <assert.h> 中,其做用是先计算表达式expression的值为假(即为0),那么它就先向stderr打印一条出错信息,而后经过条用abort来终止程序;express

使用assert的缺点是,频繁的调用会极大的影响程序的性能,增长额外的开销。编程

下面实际使用一下 assert函数

#include <assert.h>

#include <iostream>
// #include <cassert>
using namespace std;
int main() {
    cout << "====assert test====\n";
    assert(true);    //表达式为真
    assert(1 >= 2);  //表达式为假
    return 0;
}

在 VS Code 中运行(Ctrl + Alt + N)性能

出现异常单元测试

上面这个错误是很典型异常,能够考虑用assert排查。测试

根据提示咱们很快就能定位到错误点,就在assert(1 >= 2)处;既然assert这么便于定位出错点,在工程中使用它就显得颇有必要;但其也有必定的使用规则;spa

断言语句不会永远被执行,能够屏蔽也能够启用,这就要求assert不论是在屏蔽仍是启用状态下都不能对咱们自己代码有所影响.操作系统

那么咱们通常在什么状况下使用断言呢?调试

主要体如今如下几个方面:

  1. 能够在预计正常状况下程序不会到达的地方放置断言。(如assert(0);)

  2. 使用断言测试方法的前置条件和后置条件;

  • 前置条件:代码执行前必须具有的特性;
  • 后置条件:代码执行后必须具有的特性;
  1. 使用断言检测类的不变状态,确保任何状况下,某个变量的状态或范围必须知足。

断言assert使用规则

固然咱们在使用断言的过程当中会有一些咱们应该注意的事项和养成一些良好的习惯,如:

  1. 每一个assert只检验一个条件,由于同时检验多个条件时,若是断言失败,咱们就没法直观的判断哪一个条件失败;

没法直观的判断哪一个条件失败:

assert(nOffset >= 0 && nOffset + nSize <= m_nInfomationSize);

只检验一个条件,比较直观:

assert(nOffset >= 0);
assert(nOffset + nSize <= m_nInfomationSize);
  1. 不能使用改变环境的语句,就像咱们上面的代码改变了i变量,在实际编写代码的过程当中是不能这样作的;

例如:

assert(i++ < 100)

错误点:这是由于若是出错,好比在执行以前i=100,那么这条语句就不会执行,那么i++这条命令就没有执行。

assert(i < 100)
i++;

正确。

  1. assert和后面的语句应该空一行,以造成逻辑和视觉上的一致性,也算是一种良好的编程习惯,让编写的代码有一种视觉上的美感;

  2. 有的地方,assert不能代替条件过滤;

程序通常分为Debug 版本和Release 版本,Debug 版本用于内部调试,Release 版本发行给用户使用。断言assert 是仅在Debug 版本起做用的宏,它用于检查"不该该"发生的状况。

  1. 放在函数参数的入口处检查传入参数的合法性;
int resetBufferSize(int nNewSize) {
    //功能:改变缓冲区大小,
    //参数:nNewSize 缓冲区新长度
    //返回值:缓冲区当前长度
    //说明:保持原信息内容不变 nNewSize<=0表示清除缓冲区
    assert(nNewSize >= 0);
    assert(nNewSize <= MAX_BUFFER_SIZE);
    ...
}

在咱们使用C语言/C++作工程项目时,若是咱们能在代码中合理的使用assert,能使咱们建立更稳定、质量更好且不易于出错的代码;当须要在一个值为false时中断当前操做的话就可使用断言。

单元测试必须使用断言;另外除了类型检查和单元测试外,断言还提供了一种肯定各类特性是否在程序中获得维护的极好的方法;