断言(assert)的用法

2023-11-05

我一直以为 assert 仅仅是个报错函数,事实上,它居然是个宏,并且作用并非"报错"。

在经过对其进行一定了解之后,对其作用及用法有了一定的了解,assert() 的用法像是一种"契约式编程",在我的理解中,其表达的意思就是,程序在我的假设条件下,能够正常良好的运作,其实就相当于一个 if 语句:

if(假设成立)
{
     程序正常运行;
}
else
{
      报错&&终止程序!(避免由程序运行引起更大的错误)  
}

但是这样写的话,就会有无数个 if 语句,甚至会出现,一个 if 语句的括号从文件头到文件尾,并且大多数情况下,我们要进行验证的假设,只是属于偶然性事件,又或者我们仅仅想测试一下,一些最坏情况是否发生,所以这里有了 assert()。

assert 宏的原型定义在 assert.h 中,其作用是如果它的条件返回错误,则终止程序执行。

#include "assert.h" 
void assert( int expression );

assert 的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向 stderr 打印一条出错信息,然后通过调用 abort 来终止程序运行。

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

在调试结束后,可以通过在包含 #include 的语句之前插入 #define NDEBUG 来禁用 assert 调用,示例代码如下:

#include 
#define NDEBUG 
#include

用法总结与注意事项

1)在函数开始处检验传入参数的合法性

如:

int resetBufferSize(int nNewSize) 
{ 
//功能:改变缓冲区大小, 
//参数:nNewSize 缓冲区新长度 
//返回值:缓冲区当前长度 
//说明:保持原信息内容不变 nNewSize<=0表示清除缓冲区 
assert(nNewSize >= 0); 
assert(nNewSize <= MAX_BUFFER_SIZE); 
 
... 
}

2)每个assert只检验一个条件,因为同时检验多个条件时,如果断言失败,无法直观的判断是哪个条件失败

不好:

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

好:

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

3)不能使用改变环境的语句,因为assert只在DEBUG个生效,如果这么做,会使用程序在真正运行时遇到问题

错误: 

assert(i++ < 100)

这是因为如果出错,比如在执行之前i=100,那么这条语句就不会执行,那么i++这条命令就没有执行。

正确:

assert(i < 100)
i++; 

4)assert和后面的语句应空一行,以形成逻辑和视觉上的一致感

5)有的地方,assert不能代替条件过滤   

程序一般分为Debug 版本和Release 版本,Debug 版本用于内部调试,Release 版本发行给用户使用。断言assert 是仅在Debug 版本起作用的宏,它用于检查"不应该"发生的情况。以下是一个内存复制程序,在运行过程中,如果assert 的参数为假,那么程序就会中止(一般地还会出现提示对话,说明在什么地方引发了assert)。

以下是使用断言的几个原则:

  • 使用断言捕捉不应该发生的非法情况。不要混淆非法情况与错误情况之间的区别,后者是必然存在的并且是一定要作出处理的。
  • 使用断言对函数的参数进行确认。
  • 在编写函数时,要进行反复的考查,并且自问:"我打算做哪些假定?"一旦确定了的假定,就要使用断言对假定进行检查。
  • 一般教科书都鼓励程序员们进行防错性的程序设计,但要记住这种编程风格会隐瞒错误。当进行防错性编程时,如果"不可能发生"的事情的确发生了,则要使用断言进行报警。

ASSERT ()是一个调试程序时经常使用的宏,在程序运行时它计算括号内的表达式,如果表达式为FALSE (0), 程序将报告错误,并终止执行。如果表达式不为0,则继续执行后面的语句。这个宏通常原来判断程序中是否出现了明显非法的数据,如果出现了终止程序以免导致严重后果,同时也便于查找错误。

ASSERT 只有在 Debug 版本中才有效,如果编译为 Release 版本则被忽略。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

断言(assert)的用法 的相关文章

  • 区间预测

    区间预测 MATLAB实现基于QRCNN GRU Multihead Attention多头注意力卷积门控循环单元多变量时间序列区间预测 目录 区间预测 MATLAB实现基于QRCNN GRU Multihead Attention多头注意
  • SpringCloud Stream 消息同步和异步

    1 异步的形式有 通知 单向请求 只管发送不关心结果 请求 异步响应 一对一的交互 请求的信息不回立马返回 而是过一段时间再返回结果 消息 利用消息可以实现一对多形态的交互 2 MQ的应用场景 异步处理 流量削锋 日志处理 应用解耦 3 p

随机推荐

  • 网络安全实验室6.解密关

    6 解密关 1 以管理员身份登录系统 url http lab1 xseclab com password1 dc178aa12e73cfc184676a4100e07dac index php 进入网站点击忘记密码的链接 进入到重置密码的
  • 开源进展

    作为连接实体对象 人或物 的现实身份与链上身份的可信映射 实现实体对象之间安全可信的数据授权与交换 分布式身份技术解决方案在推动区块链应用繁荣及可信数据流转的过程中扮演着重要角色 WeIdentity是由微众银行自主研发并完全开源的一套分布
  • 用python读取txt文件中的数据并画各类图形展示

    捣腾了一下午 终于整出来了 帮助和我一样的菜鸟解决数据读取问题 这是所有做实验的第一步 如果这步都没有解决 下面部分如何展开 这里每一步都很详细的解释了如何操作 我的文件内容 读取数据和画图都在本文末尾都有展示 import pandas
  • 【TensorFlow-windows】(二) 实现一个去噪自编码器

    主要内容 1 自编码器的TensorFlow实现代码 详细代码注释 2 该实现中的函数总结 平台 1 windows 10 64位 2 Anaconda3 4 2 0 Windows x86 64 exe 当时TF还不支持python3 6
  • nvidia-smi 命令详解

    nvidia smi 命令详解 1 nvidia smi 面板解析 2 显存与GPU的区别 Reference nvidia smi命令详解 相关文章 nvidia smi nvcc V 及 CUDA cuDNN 安装 nvidia smi
  • 用Java实现简单计算器

    实训题 8 简单计算器 一 项目说明 实训目的 掌握 Java GUI 开发中的布局管理和事件处理机制 实训要求 1 要使用 java 的 GUI 设计出计算器界面 2 通过界面按钮 可以实现整数或浮点数的四则运算 并能将结果显示在界面中
  • 2020-01-24

    新年快乐 祝各位粉丝以及csdn的朋友 新年快乐 2020没有解决不了的问题 加油
  • Linux/Centos源码安装python3任意版本

    首先安装编译工具 sudo yum y install cmake3 glib2 devel libpcap libpcap devel libgcrypt devel glib2 devel qt devel qt5 qtbase dev
  • js小学生图区_多种方式实现js图片预览

    js多种方式图片预览 持续更新 设置自己的变量存储区 var Util file file image show img show Util file nchange function f if this files 0 type inde
  • IDEA 使用技巧

    1 idea展开折叠类中所有方法 展开 ctrl shift 折叠 ctrl shift 2 Idea中设置注释位置 自动缩进到合适位置
  • 【PID控制算法】

    PID控制小解 比例环节 P 成比例的反映偏差信号 偏差一旦产生 控制器立即产生控制作用 较小误差 积分环节 I 主要用于消除静态误差 提高系统得无差度 积分作用的强弱取决于积分时间常数 Ti Ti越 大 积分作用越弱 反之越强 微分环节
  • 如何改进研发项目文档内容质量?

    书接上回 研发项目文档重要吗 个人以为 改进研发项目文档内容质量 需要深入研发流程 梳理研发流程中的信息需求和依赖关系 完善相关的内容规范 模板 和评审规范 从系统上保障研发文档的质量 所以这段时间 协调痛点场景作为改进试点 参与到研发设计
  • 从控制理论的根轨迹法和稳定性分析谈到舵机PD控制代码实现

    在上一次谈到基于MPU6050的基于一阶互补滤波算法实现后 本来想接着就自适应一阶互补滤波和卡尔曼滤波再写一篇的 但是卡尔曼滤波算法我自己写出来并进行姿态解算后发现效果不很好 才疏学浅 等我调好了再写吧 昨天花了半下午做了一个基于MPU60
  • Visual Studio 2017 设置透明背景图

    一 前言 给大家分享一下 如何为VS2017设置透明背景图 下面是一张设置前和设置后的图片 设置前 设置后 二 设置背景图片的扩展程序 我们打开VS的扩展安装界面 工具 gt 扩展和更新 gt 联机 输入 Background 可以看到有两
  • Mysql偶尔连接失败的问题

    在项目中 偶尔会出现获取jdbc连接失败的报错 其中有一种因为连接失效的报错 The last packet successfully received from the server was 1 312 227 milliseconds
  • 时序预测:从两篇高影响力的论文谈起

    未来可以预测吗 本文从两篇高影响力的时序预测文章谈起 其中一篇是18年放在arXiv上的文章 文中总结性地提出了时序卷积网络 TCN Temporal Convolutional Network 短短两三年引用数已经破千 TCN作为一种基准
  • java常用集合之Map

    目录 Map集合基本内容 特点 扩容 遍历 Map集合实现 1 HashMap 基本原理 Table数组中的的Node 2 HashTable 3 ConcurrentHashMap 4 TreeMap 5 LinkedHashMap Ma
  • 关于启动fabric网络错误:cryptogen tool not found. exiting

    在启动fabric中first network网络时 需要执行一个自动化脚本 byfn sh m generate 该脚本需要自动生成相关证书信息 fabric官方提供了两款工具 configtxgen cryptogen 在脚本执行中会从
  • JUnit5学习之六:参数化测试(Parameterized Tests)基础

    项目主页 https github com zq2599 blog demos 该项目在GitHub上的主页 git仓库地址 https https github com zq2599 blog demos git 该项目源码的仓库地址 h
  • 断言(assert)的用法

    我一直以为 assert 仅仅是个报错函数 事实上 它居然是个宏 并且作用并非 报错 在经过对其进行一定了解之后 对其作用及用法有了一定的了解 assert 的用法像是一种 契约式编程 在我的理解中 其表达的意思就是 程序在我的假设条件下