C++之assert、NDEBUG探究
相关博文:C++之异常处理探究
相关博文:assert、if else、try catch三者的区别
assert
编写代码时,我们总是会做出一些假设,assert就是用于在代码中捕捉这些假设。assert表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式值为真,可以在任何时候启用和禁用assert验证,因此可以在测试时启用assert而在部署时禁用assert。同样,程序投入运行后,最终用户在遇到问题时可以重新启用assert。
简单来说如果结果和你的预期一样,那么OK,结果为真继续运行.如果结果和预期不符,那么程序会抛出一个系统级错误(不是异常),并且终止程序运行。
用法
assert宏的原型定义在<assert.h>中,其作用是先计算表达式expression的值为假(即为0),那么它就先向stderr打印一条出错信息,然后通过条用abort来终止程序;
例1:
运行报错:
linux下运行:
已放弃使用assert()的原因是,频繁的调用会极大的影响程序的性能,增加额外的开销。在调试结束后,可以通过在包含#include <assert.h>的语句之前插入 #define NDEBUG 来禁用assert调用,示例代码如下:
附例1代码:
//小问学编程
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>int main( void )
{FILE *fp;//以可写的方式打开一个文件,如果不存在就创建一个同名文件fp = fopen( "test.txt", "w" );//所以这里不会出错assert( fp ); fclose( fp );//以只读的方式打开一个文件,如果不存在就打开文件失败fp = fopen( "noexitfile.txt", "r" );//所以这里出错assert( fp ); //程序永远都执行不到这里来fclose( fp ); return 0;
}
例2:正常运行
例3:将例2中i的初始值改为0,报错!
附例3代码:
//小问学编程
#include <stdio.h>
#include <assert.h>
int main(void)
{int i;i = 0;assert(i++);printf("%d\n",i);return 0;
}
上面这个错误是很典型异常,可以考虑用assert排查。
根据提示我们很快就能定位到错误点,就在assert(i++)处;既然assert这么便于定位出错点,在工程中使用它就显得很有必要;但其也有一定的使用规则;
assert语句不会永远被执行,可以屏蔽也可以启用,这就要求assert不管是在屏蔽还是启用状态下都不能对我们本身代码有所影响,这样刚才我们在代码中使用的assert(i++)就不行,因为如果禁用了assert,那i++就不能执行;正确的做法应该是:assert(i);i++;那么我们一般在什么情况下使用assert呢?
主要体现在以下几个方面:
1. 可以在预计正常情况下程序不会到达的地方放置assert。(如assert(0);)
2. 使用assert测试方法的前置条件和后置条件;
前置条件:代码执行前必须具备的特性;
后置条件:代码执行后必须具备的特性;
3. 使用assert检测类的不变状态,确保任何情况下,某个变量的状态或范围必须满足。
assert使用规则
1. 每个assert只检验一个条件,因为同时检验多个条件时,如果assert失败,我们就无法直观的判断哪个条件失败;
2. 不能使用改变环境的语句,就像我们上面的代码改变了i变量,在实际编写代码的过程中是不能这样做的;
例如:
3. assert和后面的语句应该空一行,以形成逻辑和视觉上的一致性,也算是一种良好的编程习惯,让编写的代码有一种视觉上的美感;
4. 有的地方,assert不能代替条件过滤;程序一般分为Debug 版本和Release 版本,Debug 版本用于内部调试,Release 版本发行给用户使用。assert是仅在Debug 版本起作用的宏,它用于检查"不应该"发生的情况。
5. 放在函数参数的入口处检查传入参数的合法性;
在我们使用C语言/C++做工程项目时,如果我们能在代码中合理的使用assert,能使我们创建更稳定、质量更好且不易于出错的代码;当需要在一个值为FALSE时中断当前操作的话就可以使用assert。
单元测试必须使用assert;另外除了类型检查和单元测试外,assert还提供了一种确定各种特性是否在程序中得到维护的极好的方法;
附:《C++ Primer》第5版 6.5.3调试帮助:
可以使用这些常量在错误消息中提供更多信息:
——《C++ Primer》第5版 6.5特殊用途语言特性
C++之assert、NDEBUG探究相关推荐
- c++ 函数 -函数重载 -特殊用途的语言特性(默认实参,内联函数 ,constexpr ,assert,NDEBUG)
c++ 函数 -函数重载 -特殊用途的语言特性 文章目录 c++ 函数 -函数重载 -特殊用途的语言特性 函数重载 定义: 重载和const形参 const_cast 和重载 const_cast 重 ...
- C++新特性探究(十二):static_assert(提前判误)
相关博文:C++之异常处理探究 相关博文:assert.if else.try catch三者的区别 相关博文:C++之assert.NDEBUG探究 相关博文:static_assert和asser ...
- C++之异常处理探究
相关博文:C++之assert.NDEBUG探究 异常简介: 异常处理,是编程语言或计算机硬件里的一种机制,用于处理软件或信息系统中出现的异常状况(即超出程序正常执行流程的某些特殊条件). 在 ...
- C++宏assert()
断言,是宏,而非函数.assert 宏的原型定义在 <assert.h>(C).<cassert>(C++)中,其作用是如果它的条件返回错误,则终止程序执行.可以通过定义 ND ...
- C 标准库 - assert.h
C 标准库 - <assert.h> 简介 C 标准库的 assert.h头文件提供了一个名为 assert 的宏,它可用于验证程序做出的假设,并在假设为假时输出诊断消息. 已定义的宏 a ...
- 【 C 】assert.h 简明介绍
头文件<assert.h>唯一的目的就是提供assert宏定义,可以在程序中关键的地方使用这个宏来进行断言.如果一处断言被证明非真,希望程序在标准错误流输出一条适当的提示信息,并使执行异常 ...
- ASSERT(断言)的用法
我一直以为assert仅仅是个报错函数,事实上,它居然是个宏,并且作用并非"报错". 在经过对其进行一定了解之后,对其作用及用法有了一定的了解,assert()的用法像是一种&qu ...
- C语言assert的用法
assert宏的原型定义在<assert.h>中,其作用是如果它的条件返回错误,则终止程序执行,原型定义: #include <assert.h> void assert( i ...
- KVM 虚拟化原理探究--启动过程及各部分虚拟化原理
KVM 虚拟化原理探究- overview 标签(空格分隔): KVM 写在前面的话 本文不介绍kvm和qemu的基本安装操作,希望读者具有一定的KVM实践经验.同时希望借此系列博客,能够对KVM底层 ...
最新文章
- iphone-common-codes-ccteam源代码 CCGraphics.m
- 1.11 实例:字符串替换
- pe修改rpc服务器不可用,ABBYY FineReader 12出现“RPC服务不可用”怎么办
- 【Linux小技巧】开启关闭蜂鸣声
- href中使用javascript:void(0)无法执行操作
- 网络货运平台要智能,安全的数据底座少不了
- python3连接oracle 11G数据库
- platform_device_add()函数分析
- VB 打开文件夹,并选中指定的文件
- Android自定义PreferenceScreen的Layout布局,并获取控件
- 7-28 | 猴子选大王
- 二台电脑之间数据库文件进行备份
- 平头哥智能语音CB5654开发板如何读取云端的返回值
- 2023最新支付宝微信运动步数网页源码+附带原始接口
- Java实例教程(上)
- ElasticSeach详细安装教程--图文介绍超详细
- 《语雀 IT 百科》发布了!
- 程序员练级攻略(2018)-陈皓-笔记整理
- ue4渲染速度太慢_[UE4]性能优化指南(程序向)
- RealPlayer.11.6.0.14.748 新体验
热门文章
- 注解形式控制器 数据验证,类型转换(2)
- 基于JAVA+SpringBoot+Mybatis+MYSQL的汽车租赁系统
- 基于JAVA+SpringMVC+Mybatis+MYSQL的员工事物管理系统
- 基于JAVA+SpringMVC+Mybatis+MYSQL的甜品店商城
- php任务奖励体系,phpwind7.5完备的积分体系
- 每日一算法 ---- 冒泡排序
- ELK之收集haproxy日志
- 查找算法(一)顺序查找
- mysql 以及mysql可视化工具下载安装地址
- 如何破解linux用户帐号密码二