C++ assert宏实现原理
来源:互联网 发布:android书籍推荐 知乎 编辑:程序博客网 时间:2024/06/11 14:00
assert(expression);
若expression表达式为false,当前进程会调用abort终止运行,并且会向stderr写一条消息。
这条消息根据不同的实现有所不同,但是至少会包括,assert所在的源文件的文件名,行号,及对对应的expression。
另外,若在release状态下,assert宏会被自动remove掉。
我对assert宏的实现非常感兴趣。显然,如果了解了其实现原理,那么我们可以自己实现类似于assert的宏。
#define __CRT_WIDE(_String) L ## _String#define _CRT_WIDE(_String) __CRT_WIDE(_String)
assert宏的定义如下:
#ifdef NDEBUG#define assert(_Expression) ((void)0)#elsevoid _wassert(const wchar_t * _Message, const wchar_t *_File, unsigned _Line);#define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )#endif
release状态下会定义NDEBUG宏,此时assert什么也不做。在DEBUGU状态下,assert(_Expression)首先被替换成||表达式。根据||表达式的规则首先计算(!!(_Expression))的值,如果为true,||后面的表达式不会做计算。如果为false,将会计算后面的表达式。然而,后面的表达式是一个_wassert函数调用,对应的参数为_Expression对应的字条串,assert所在的文件名,及行号。
mingw的_wassert函数实现如下:
extern 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);elseOutputDebugStringW(msgbuf);abort ();}
显然,上面的实现不难。msbuf中存放的就是要打印的输出。根据不同的app类型,输出方式不一样。如果是普通的命令行方式,输出到stderr。如果是图形应用,估计会跳出一个窗口吧!程序最后会调用一个abort,结束程序。当然,进程都结束了,msbuf会自动释放,没必要手工释放了。
Interesting!!
0 0
- C++ assert宏实现原理
- c实现assert
- assert用法,原理,改编(C++)
- assert的实现原理浅析
- assert宏的原理
- C语言assert宏
- assert用法及实现assert宏
- assert宏的实现
- assert宏的实现
- assert.h原理以及自己的实现
- C语言之宏assert
- c/c++ assert宏用法
- C++ C语言assert()宏
- C标准库<assert.h>实现
- assert增强宏的实现
- C++ Assert
- assert宏的用法及原理
- [C-Library]assert.h - assert()
- Fragment实现TabHost标签切换功能
- android中可以通过两种方式发送短信
- Unity3D性能优化总结
- FineReport助飞鹤乳业建报表系统
- OpenGL ES着色器语言之变量和数据类型(二)(官方文档第四章)
- C++ assert宏实现原理
- c# 项目间相互引用
- 在Xcode中使用Git进行源码版本控制
- 数据库碎片学习:SQL->join关键字
- Makefile中的wildcard用法
- sigle end and differential primary
- java实现定时任务的三种方法
- javah的使用:有包名与无包名的类生成.h头文件
- Js和C#中的字符串编码解码