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 ...
随机推荐
- 浅谈Java语言中try{}catch{}和finally{}的执行顺序问题
浅谈Java语言中try{}catch{}和finally{}的执行顺序问题 2019-04-06 PM 13:41:46 1. 不管有没有出现异常,finally块中代码都会执行: 2. 当t ...
- vue中使用postMessage进行跨越传值
想在“当前位置”获取子页面的title属性,但是main页面和子页面在不同的端口上,直接获取会出现: “Blocked a frame with origin from accessing a cro ...
- nginx配置ssl验证
在上一篇博客中,我们只是通过nginx搭建了反向代理服务,由于需要在小程序中使用https服务,所以需要申请安全证书. 1.在所购买的域名商那申请免费的ssl证书,我买的是阿里的,所以直接在阿里上申请 ...
- Spring Cloud 微服务笔记(七) Zuul入门
Zuul入门 Zuul是从设备和网站到后端应用程序所有请求的前门,为内部服务提供可配置的对外URL到服务的 映射关系,基于JVM的后端路由器.其具备一下功能: 1)认证与授权 2)压力控制 3)金丝雀 ...
- Python3 文件
f=open('C:\\Users\\fengx\\Desktop\\sharing\\test.txt') 如果打开文件的格式不匹配,可能会报如下错: >>> open('C:\U ...
- Ubuntu安装MySQL和Python库MySQLdb步骤
一.安装MySQL服务器和客户端 执行以下命令: sudo apt-get install mysql-server-5.6 mysql-client-5.6 sudo apt-get install ...
- 上传插件webupload之调用拍照兼容问题
在项目中,移动端用到了webupload插件来实现上传功能(我觉得这个插件挺好用的,所以无论pc还是移动端我都使用了这个插件来做上传功能) 在移动端要调起拍照功能,实现上传,须得在webuploade ...
- Hive 本地调试方法
关键词:hive, debug 本地调试(local debug) Hive 可分为 exec (hive-exec,主要对应源码里的ql目录) 和 metastore 两部分,其中exec对外有两种 ...
- php代码进行跨域请求处理
以下的函数作为每个请求的前置操作 (thinkphp框架) public function appInit(&$params) { header('Access-Control-Allow-O ...
- js面向对象和php面向对象的区别
---恢复内容开始--- js的面向对象 1.类 具体相同的特征的一些对象的集合. 2.对象 具体到某一个失误了都可以叫做对象. 3.类 通过function 定义类 所以在js里类的本质是函数, ...