C++ 断言

assert宏 (基本概念与用法整理)

assert宏的深入学习

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不是常量,静态断言是不符合语法的。

时间: 2024-12-17 23:23:55

C++ 断言的相关文章

jmeter之json数据参数化 断言等

在 http Load Testing 中,json 数据的提交是个让人头疼的问题.本文详细介绍如何进行 JMeter 的 json 测试提交,以及如何将其参数化.Step 1 http json 请求采样器的录制 这个工具很多,可以使用 JMeter 代理录制,也可以使用 Badboy. Step 2 为该采样器添加 HTTP 信息管理器鼠标右击该采样器,右键菜单选择 "添加" -> 配置元件 -> HTTP 信息头管理器,然后信息头添加一条名称为 Content-Typ

Fiddler+Jmeter+断言详细教程

一.Fiddler抓包工具的配置和使用 在编写网关自动化脚本之前,得先学会如何抓包,这里以Fiddler为例.会抓包的同学可以跳过这一步,当然看看也是没坏处的…… 局域网络配置 将要进行抓包的手机与电脑连入同一局域网,电脑才能够抓到手机APP的请求,这里介绍一种我们在使用的网络配置方法. 首先使用电脑A布置一个我们抓包需要的局域网.下载猎豹WiFi(网上有很多这种工具360免费WiFi.百度WiFi等,随意下载一个就好,这里我们以猎豹WiFi为例),安装完后创建一个WiFi即可. 然后使用抓包的

jmete 学习 --元件详解之断言

断言组件用来对服务器的响应数据做验证,常用的断言是响应断言,其支持正则表达式.本篇我们来介绍一些常用的断言. 1. BeanShell Assertion BeanShell 作为脚本语言能够方便的调用java 类,也可以访问Jmeter 的诸多属性,具体有: log对象,可以利用此来写对象日志. SampleResult对象,可以从中获取响应数据,响应吗等信息,只读. Respons对象,获取响应数据,只读. Failure,用来设置断言成功与否,Boolean类型. FailureMessa

SOAPUI使用脚本进行断言

Script-Assertion允许对消息进行任意验证,包括消息内容,HTTP头等.Script-Assertion使用脚本语言(Groovy或JavaScript)编写.使用标准的"Add Assertion"按钮将Script-Assertion添加到TestStep中; 这将显示以下配置对话框 顶部区域是标准的soapUI脚本编辑器,具有相应的弹出菜单和操作.运行按钮针对上次接收到的响应执行断言脚本,并将结果显示在弹出窗口中.底部显示脚本中可用的日志变量的输出. 脚本中的mess

JMeter接口测试——断言

断言是什么呢,它是用来检查返回结果对不对的. 用来验证结果是否正确,如果正确的话,就代表这个请求的返回是正确的,如果没有的话就代表这个请求的结果和我们预期的不一致,这样我们就可以通断言来检查返回结果,测试是否通过. ..响应结果中需包含"200". 查看执行结果 .

Selenium2+python自动化56-unittest之断言(assert)

前言 在测试用例中,执行完测试用例后,最后一步是判断测试结果是pass还是fail,自动化测试脚本里面一般把这种生成测试结果的方法称为断言(assert). 用unittest组件测试用例的时候,断言的方法还是很多的,下面介绍几种常用的断言方法:assertEqual.assertIn.assertTrue 一.简单案例 1.下面写了4个case,其中第四个是执行失败的 # coding:utf-8import unittestclass Test(unittest.TestCase):   

C++11 新特性,运行时断言与静态断言

C98或C99中的库为:<cassert> 或<assert.h> 运行时断言,故明思议是当程序在运行的时候才作为判决,可以认为是对参数的有效性的判断. 而静态断言,是对参数的条件判断提前做了,在预编译的时候进行完成的.如: //demo1.cpp #include <cassert> using namespace std; char *arrayAolloc(int n){ assert(n>0); return new char [n]; } int mai

java 断言

面试的时候遇到了一个什么时候才使用assert的问题----断言 当时懵了,不知道如何回答,结果面试官也说assert----断言在c语言中使用的可能比较多,java的话除非学的比较深,不然一 般不会了解到.委婉的给了基础不扎实的我一个台阶下吧.首先来看看java的api文档,来看看java.lang.Throwable类. The Throwable class is the superclass of all errors and exceptions in the Java languag

grep及正则表达式 含(含断言)

grep和正则表达式 1.grep:Global search REgular expression and Print out the file 作用:文本搜索工具,根据用户指定的模式对目标文件逐行进行匹配,打印匹配到的行 模式:由正则表达式字符及文本字符编写的过滤条件 格式: grep [options] pattern file[...] --color=auto 对匹配到的文本着色显示 -v 显示不能够被pattern匹配的行 -i 忽略file中文件字符的大小写 -n 显示匹配的行号

Swift之:断言(Assertions)

断言(Assertions) Optionals使得我们可以检测值是否存在.在某些情况下,如果某个值不存在或者没有提供特定的满足条件,代码不应该继续往下执行. 在这些情况下,可以使用触发断言来终止执行并提供调试. 断言是在运行时检测条件是否为true,如果为true,就继续往下执行,否则就在这里中断. 断言对应的关键字是assert 如: let age = 18 // 这里age >= 18表示式的结果是true,所以这里断言什么也不做,代码继续往下执行 assert(age >= 18,