ASSERT整理

来源:互联网 发布:im即时通讯源码java 编辑:程序博客网 时间:2024/06/06 17:48

assert的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。

assert的宏定义在#include <assert.h>

具体代码如下

****assert.h - define the assert macro**       Copyright (c) Microsoft Corporation. All rights reserved.**Purpose:*       Defines the assert(exp) macro.*       [ANSI/System V]**       [Public]*****/#ifdef _CRTBLD#ifndef _ASSERT_OK#error assert.h not for CRT internal use, use dbgint.h#endif  /* _ASSERT_OK */#include <cruntime.h>#endif  /* _CRTBLD */#include <crtdefs.h>#undef  assert#ifdef NDEBUG#define assert(_Expression)     ((void)0)#else  /* NDEBUG */#ifdef __cplusplusextern "C" {#endif  /* __cplusplus */_CRTIMP void __cdecl _wassert(_In_z_ const wchar_t * _Message, _In_z_ const wchar_t *_File, _In_ unsigned _Line);#ifdef __cplusplus}#endif  /* __cplusplus */#define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )#endif  /* NDEBUG */
分析:

assert的使用场景 在debug模式下使用,如果非debug模式表达式会被替换为(void)0

宏如果这样做在运行的时候直接将这一行越过不进行汇编所以NDEBUG的assert不会被执行;

所以void((0))是指编译器不对这一行进行编译直接去下一行

#define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )


参数分析如果第一个表达式就是对asset中的bool表达式就行判断是真的话后面的表达式就不用看了,assert直接替换结果如果是假就要看后面的表达式,后面的表达式是一个函数具体的如下第一个参数就是你的表达式的字符串,

函数代码如下继续分析

xtern int mingw_app_type;        void __cdecl _wassert(const wchar_t *_Message,const wchar_t *_File,unsigned _Line)  {      wchar_t *msgbuf = (wchar_t *) malloc (8192*sizeof(wchar_t));        if (!_File || _File[0] == 0)          _File = L"<unknown>";        if (!_Message || _Message[0] == 0)          _Message = L"?";        _snwprintf (msgbuf, 8191,          L"Assertion failed!\n\nFile: %ws, Line %u\n\nExpression: %ws",          _File,_Line, _Message);        if (mingw_app_type == 0)          fwprintf (stderr, L"%ws\n", msgbuf);      else          OutputDebugStringW(msgbuf);        abort ();  }  
这个代码的逻辑如下后两个参数不需要去分析下具体就是将asset中的内容打印在屏幕是上并调用abort终止程序

所以在使用assert中应注意一下几点

每个assert只检验一个条件,因为同时检验多个条件时,如果断言失败,无法直观的判断是哪个条件失败

不用再asset中改变需要断言的变量的值否则在非debug模式下不能使用。

assert不要作为条件判断,因为不满足之后直接回终止掉进程

asset断言只会停止到当前,并且对后面的错误没办法直接观察到。



原创粉丝点击