C++ 断言
1、运行时断言
1.1、assert属于运行时断言,可以在运行时判断给定条件是否为真,如果为真则什么也不做,否则打印一跳错误信息,然后通过abort来终止程。当程序开发阶段,我们可以在debug模式下加入大量的运行时断言,来提高我们程序的健壮性,并且提高开发速度。但是当程序需要发布的时候,大量的断言会影响程序的运行效率,此时我们只需要在assert.h头文件前加#define NDEBUG.
1.2、断言有一个问题,就是一定会abort,强制整个程序退出而导致调试也无法继续进行,就像上图这样,出现问题后,我们知道了出现问题的行号,但是我们需要手动在该行的上面设置断点,重新开始调试才能够检查到发生问题时各个变量的状态。而且,有时问题不是那么容易重现,于是就可能出现没法重现错误再检查状态的问题。
所以,我们可以自己写一个类似的宏来解决这个问题,我们希望在违反断言时触发断点陷阱门中断而不是调用abort,这样,在违反断言时程序会暂停下来,等待程序员来检查当前的状态有何异常
#define _ASSERT(x) if (!(x)) __asm {int 3}; //是检查断言,然后如果断言结果为false(0),那么就调用内联汇编指令int 3陷入调试中断
1.3、用户自定义断言
实现功能:断言的时候可以支持变量输出SMART_ASSERTvalue && "Invalid value!")("1")(s);
//头文件
////////////////////////////////////////////////////////////////////////////////
#include
#include
#include
#include
class Assert
{
public:
//编译期,SMART_ASSERT宏被替换,断言被命中时
//1、如果断言后跟有括号括起来的参数时
//SMART_ASSERT_C和SMART_ASSERT_N将不会被认为是成员,而是SMART_ASSERT_C(x)和SMART_ASSERT_N(x)宏
//间接替换为调用ShowMemoryValue成员方法。
//2、如果断言命中时后边无括号,则SMART_ASSERT_C被认为是成员变量;
//如果断言命中时后边括号在多次宏替换之后没有啦,则SMART_ASSERT_OP宏被替换后的最后一个.调用被认为是成员变量调用
Assert & SMART_ASSERT_C;
Assert & SMART_ASSERT_N;//SMART_ASSERT_C和SMART_ASSERT_N循环调用,来解析断言后边追加的参数
Assert( const wchar_t *wexpr
, const wchar_t *wfile
, const char * expr
, const char * file
, unsigned line)
: _Expr(wexpr)
, _File(wfile)
, _Line(line)
, _CFile(file)
, _Message(expr)
, SMART_ASSERT_C(*this)
, SMART_ASSERT_N(*this)
{
};
~Assert();
//如果需要支持打印多种数据类型,可以对该方法的第二个参数重载,或者对SMART_ASSERT_OP宏的进行修改,传入参数x时强制转换
为string类型
Assert & RestoreMemoryValue(const char * key, const std::string &val);
private:
std::wstring _Expr;//异常表达式
std::wstring _File;//文件名称
unsigned _Line;//文件行数
std::string_CFile;//文件名称
std::string_Message;//异常消息
std::map _memoryValue;//内存变量值
};
#ifdef SMART_ASSERT
#undef SMART_ASSERT
#endif
#define SMART_ASSERT_C(x)SMART_ASSERT_OP(x, N)
#define SMART_ASSERT_N(x)SMART_ASSERT_OP(x, C)
#define SMART_ASSERT_OP(x, next) \
SMART_ASSERT_C.RestoreMemoryValue(#x, (x)).SMART_ASSERT_##next
#define SMART_ASSERT(expr) \
if ( (expr) ); \
else Assert(_CRT_WIDE(#expr), _CRT_WIDE(__FILE__), #expr, __FILE__, __LINE__).SMART_ASSERT_C
//实现
////////////////////////////////////////////////////////////////////
#include
#include "SmartAssert.h"
//https://msdn.microsoft.com/zh-cn/library/9sb57dw4.aspx :_wassert说明
Assert::~Assert()
{
//获取_memoryValue临时变量值打印
//进入中断
_wassert(_Expr.c_str(), _File.c_str(), _Line);
}
Assert & Assert::RestoreMemoryValue(const char *key, const std::string &val)
{
_memoryValue[key] = val;
return *this;
};
2、静态断言
在2011年的C++标准中出现了静态断言(static_assert)的语法,所谓静态断言,就是在编译时就能够进行检查的断言,static_assert
是C++的标准语法,不需要引用头文件。静态断言的另一个好处是,可以自定义违反断言时的编译错误信息。
例如:
const int i = 22;
static_assert(i != 22, "i equals to 22");//这个代码,将无法通过编译,因为i的值违反了静态断言。
注意:静态断言的限制是,断言本身必须是常量表达式,如果这样的i不是常量,静态断言是不符合语法的。
C++ 断言的更多相关文章
- iOS-----程序异常处理----- 断言NSAssert()和NSParameterAssert区别和用处
NSAssert和assert是断言,主要的差别是assert在断言失败的时候只是简单的终止程序,而NSAssert会报告出错误信息并且打印出来.所以尽管的使用NSAssert,可以不去使用asser ...
- GO语言总结(5)——类型转换和类型断言
上一篇博客介绍了Go语言的数组和切片——GO语言总结(4)——映射(Map),本篇博客介绍Go语言的类型转换和类型断言 由于Go语言不允许隐式类型转换.而类型转换和类型断言的本质,就是把一个类型转换到 ...
- postman 断言解析
最近在学习postman官方文档, 顺势翻译出来,以供学习! postman断言是JavaScript语言编写的,在postman客户端指定区域编写即可. 断言会在请求返回之后,运行,并根据断言的pa ...
- 测试框架Mocha与断言expect
测试框架Mocha与断言expect在浏览器和Node环境都可以使用除了Mocha以外,类似的测试框架还有Jasmine.Karma.Tape等,也很值得学习. 整个项目源代码: 为什么学习测试代码? ...
- JavaScrict中的断言调试
今天在看忍者秘籍的时候,看到一个断言方法.查阅了一下资料,原来javascript中的console也包含这个方法.具体用法如下: <script type="text/javascr ...
- 断言与异常(Assertion Vs Exception)
在日常编程实践中,断言与异常的界限不是很明显,这也使得它们常常没有被正确的使用.我也在不断的与这个模糊的怪兽搏斗,仅写此文和大家分享一下我的个人看法.我想我们还可以从很多角度来区别断言和异常的使用场景 ...
- 断言(Assert)与异常(Exception)
断言是被用来检查非法情况而不是错误情况,即在该程序正常工作时绝不应该发生的非法情况,用来帮助开发人员对问题的快速定位.异常处理用于对程序发生异常情况的处理,增强程序的健壮性.容错性,减少程序使用中对用 ...
- Linux Kernel 代码艺术——编译时断言
本系列文章主要写我在阅读Linux内核过程中,关注的比较难以理解但又设计巧妙的代码片段(不关注OS的各个模块的设计思想,此部分我准备写在“深入理解Linux Kernel” 系列文章中),一来通过内核 ...
- selenium自动化-java-封断言类2
封装断言类 package streamax.com; import java.util.ArrayList; import java.util.List; import org.testng.Ass ...
- selenium自动化-java-封装断言
封装的断言. 1 package com.baidu.www; import org.testng.Assert; /* * 封装断言 */ public class assertion { stat ...
随机推荐
- python 在ubuntu下安装pycurl
https://www.linuxidc.com/Linux/2016-05/131574.htm
- gzip解压文件报错
#tar -xvf jdk-8u131-linux-x64.tar.gz,执行命令后报错如下: gzip: stdin: not in gzip format tar: Child returned ...
- webstorm2018.2.3激活
一,简介 WebStorm 是jetbrains公司旗下一款JavaScript 开发工具.目前已经被广大中国JS开发者誉为"Web前端开发神器"."最强大的HTML5编 ...
- JS的常用属性
JS-------定义:基于事件和对象驱动,并具有安全性能的脚本语言. 引入:<script type=”text/javascript”>具体js代码</script> ...
- elasticsearch 文档资料
1.Function Score Query 自定义查询评分 https://www.elastic.co/guide/en/elasticsearch/reference/current/query ...
- redis + cookies 实现持久登入
通过登入把用户信息和token加载到redis中去, 将token和部分用户信息存储在cookie中, 下次登入时 判断cookie的token在redis中是否存在, 存在就把用户信息加载出来自动登 ...
- 查找更改的PeopleCode
当我们做工程包迁移时,经过会遗漏部分更改过的定义.我们可以用下面的SQL来查找变更项 变量 &OPRID =代码变更者 变量 &PROJECT 项目工程名 SELECT * FROM ...
- ko数组
数组属性监控 如果你想发现并响应一个对象的改变,就应该用监控属性(observables).如果你想发现并响应一个集合的变化,就该用监控属性数组 (observableArray).监控属性数组在显示 ...
- C# WinForm:DataTable中数据复制粘贴操作的实现
1. 需要实现类似于Excel的功能,就是在任意位置选中鼠标起点和终点所连对角线所在的矩形,进行复制粘贴. 2. 要实现这个功能,首先需要获取鼠标起点和终点点击的位置. 3. 所以通过GridView ...
- Ubuntu ARM更改为国内源
关键词:ubuntu arm ubuntu-ports 国内源 镜像 阿里源 apt apt-get install update 0%working 速度慢 rk3399 开发板 ...