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 ...
随机推荐
- log4j、使用log4j、打印sql日志
添加pom文件依赖 <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifa ...
- python基础知识练习题(一)
1.执行Python脚本的两种方式:WIN+R,cmd,命令行窗口输入:python 进入python模式输入命令行直接执行命令:编写以.py结尾的文件,写入命令行,然后运行python.exe打开 ...
- python多进程学习笔记
# coding=utf-8 from multiprocessing import Process,Pool import os import time def printf(args): # ti ...
- Git提交代码(要有GitHub账号)
分享一下Git提交模式代码(只是提交到GitHub仓库而已,没有其他的操作) 这个的前提是你已经安装了Node.js.Git 下面来看: 1. cd进入目录 2. 把当前目录变成git可以管理的仓 ...
- VMware14 安装CentOS7 实现宿主机ping通虚拟机、虚拟机ping通宿主机、虚拟机能上网且能ping通百度
本文旨在通过通过虚拟机VMware14来安装CentOS7 系统,并配置固定IP来实现在Windows系统中使用Linux环境. 本文目录: 0.本机环境 1.VMware14 初始化 1.1.安装V ...
- System.getProperty(String key)方法获取常用系统信息
其中key可以为以下选项: 1.java.version Java 运行时环境版本 2.java.vendor Java 运行时环境供应商 3.java.vendor.url Java 供应商的 UR ...
- esb和eai的区别
话说SOA也推了很多年了,出现了比如ESB.SCA.jbi等各类技术和标准,乱的很.各类比较也说的云里雾里,在下理一理,按自己的观点说说. 先说说esb和eai的区别. 个人观点:esb就是eai+设 ...
- ionic4 开发企业微信应用0
作为一个后台开发人员,几年前参与过Ionic1开发过一微信公众号的经历,所以这次开发企业微信应用,就使用了ionic,正好ionic4 rc版本发布,虽然不是正式版,作为本项目的项目经理,还是决定使用 ...
- nginx + springboot 配置
1.spring boot 访问地址http://localhost:13000/test/hello 2.配置nginx.conf文件 upstream my_ngix { server local ...
- Python爬虫(1):基础知识
爬虫基础知识 一.什么是爬虫? 向网站发起请求,获取资源后分析并提取有用数据的程序. 二.爬虫的基本流程 1.发起请求 2.获取内容 3.解析内容 4.保存数据 三.Request和Response ...