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 ...
随机推荐
- 2018-2019-2 20165239其米仁增《网络对抗》Exp1 PC平台逆向破解
一.实验内容 1.掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码(0.5分) 2.掌握反汇编与十六进制编程器 (0.5分) 3.能正确修改机器指令改变程序执行流程(0.5分) 4.能 ...
- mongodb不断刷日志的问题
项目启动不断的循环刷日志. 在log4j.properties的配置文件中加上一行关闭即可 log4j.logger.org.mongodb.driver=OFF
- Centos7安装jdk-12的详细过程
Centos7安装jdk-12的详细过程 2019-04-12 21:23:24 一.下载JDK-12版本 链接地址:官方地址 下载:jdk-12_liunx-x64_bin.tar.gz 二.检 ...
- JDK解压版制作
今天上 甲骨文 的官网,想下载一个 解压版的 jdk 1.8 结果发现: 没有解压版,只有exe版本.于是就搜索制作方法. 具体就是,双击exe版本,在最后关头要安装的时候, 重点来了! 跟他皮一下 ...
- Linux-网络综合实验
题目要求:财务部门有俩台机器acc-1和acc-2,it部门有俩台机器it-2和it-2,要求acc机器互通,it机器互通,财务部和it部机器通过路由器互通
- 小程序app.onLaunch中获取用户信息,index.onLoad初次载入时取不到值的问题
问题描述: //app.js App({ globalData:{ nickname:'' }, onLaunch: function () { let that=this; //假设已经授权成功 w ...
- 实现ssr服务端渲染
前言 前段时间寻思做个个人网站,然后就立马行动了. 个人网站如何实现选择什么技术方案,自己可以自由决定. 刚好之前有大致想过服务端渲染,加载速度快,还有 SEO 挺适合个人网站的. 所以就自己造 ...
- python中for嵌套打印图形
# 打印出九九乘法表 1 * 1 = 1 2 * 1 = 2 2 * 2 = 4 3 * 1 = 3 3 * 2 = 6 3 * 3 = 9 4 * 1 = 4 4 * 2 = 8 4 * 3 = 1 ...
- ubuntu12.4上安装minigui3.0.12
在ubuntu12.4上安装minigui3.0.12 一下载源文件 移植所需的文件可以从minigui官网下载:http://www.minigui.org/en/download/ 主要文件有: ...
- dotnetcore Http服务器研究(一)
自从dotnet core 诞生以来,发展非常强势.我们总有些需要写一个独立的http服务器的需求,我想是时候忘记httplistener 了. dotnet framework 时代建一个小的htt ...