DEBUG之assert断言

assert

assert是什么?

断言,是一个定义在<assert.h>中的一个宏,并非函数

void assert(int expression);//判断表达式的真假

assert能干什么?

  • 用来检查数据的合法性,但是频繁的调用极大的影响程序的性能,增加了额外的开销(因为异常则直接中断abort)。

assert开发

  1. 断言的目的虽然是检测数据,但不意味着它需要出现在任何判断的地方,除了它系统消耗大以外,我们也要把握编程的平衡

    名词引入:契约式编程
    契约式设计强调三个概念:前置条件,后置条件和不变式。
    前置条件发生在每个操作(方法,或者函数)的最开始,后置条件发生在每个操作的最后,不 变式实际上是前置条件和后置条件的交集。违反这些操作会导致程序抛出异常。

  2. 断言一般判断内容只为一个,为的是可以准确定位到错误的是哪个条件。当然你也可以配合&&一起使用,构成所谓的短路表达式,使得错误中断,可以打印出一定的信息。
    int result = a / b;
    assert(b != 0 && "The divisor can not be zero");
    
    与&&搭配使用,可以传递错误信息
  3. 断言只针对DEBUG版本,RELEASE版本时候需要将断言去掉,直接使用#define NDEBUG即可
    #define NDEBUG //必须写在头文件前面
    #include <assert.h>
    

    必须写在头文件前面才可以生效,因为assert在头文件中是条件编译编码的,条件便是#ifndef NDEBUG,因此写在前面才能使得assert不能生效。

  4. 如果使用#define NDEBUG意味着assert不再提供功能,且里面的函数调用也不会运行,即不会有结果,因此使用中间变量接受函数返回值最佳。
  5. #undef 可以改写宏,此处可以使用吗?答案是不可以,因为改写之后就会报错assert未定义的引用,而#define NDEBUG不会出现这样的情况,因为assert会被“清除”掉。

源码

所有的问题,读了源码之后都不是问题

#undef assert

#ifdef	__cplusplus
extern "C" {
#endif

#ifdef NDEBUG
/*
 * If not debugging, assert does nothing.
 */
#define assert(x)	((void)0)

#else /* debugging enabled */

/*
 * CRTDLL nicely supplies a function which does the actual output and
 * call to abort.
 */
_CRTIMP void __cdecl __MINGW_NOTHROW _assert (const char*, const char*, int) __MINGW_ATTRIB_NORETURN;

/*
 * Definition of the assert macro.
 */
#define assert(e)       ((e) ? (void)0 : _assert(#e, __FILE__, __LINE__))

#endif	/* NDEBUG */

#ifdef	__cplusplus
}
#endif

#endif /* Not RC_INVOKED */

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值