C++ assert宏实现原理

转载:https://blog.csdn.net/dacxu/article/details/27313799

assert(expression);

若expression表达式为false,当前进程会调用abort终止运行,并且会向stderr写一条消息。

这条消息根据不同的实现有所不同,但是至少会包括,assert所在的源文件的文件名,行号,及对对应的expression。

另外,若在release状态下,assert宏会被自动remove掉。

我对assert宏的实现非常感兴趣。显然,如果了解了其实现原理,那么我们可以自己实现类似于assert的宏。


[cpp]  view plain  copy
  1. #define __CRT_WIDE(_String) L ## _String  
  2. #define _CRT_WIDE(_String) __CRT_WIDE(_String)  

assert宏的定义如下:

[cpp]  view plain  copy
  1. #ifdef  NDEBUG  
  2.   
  3.     #define assert(_Expression)     ((void)0)  
  4.   
  5. #else  
  6.   
  7.     void _wassert(const wchar_t * _Message, const wchar_t *_File, unsigned _Line);  
  8.     #define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )  
  9.   
  10. #endif    

release状态下会定义NDEBUG宏,此时assert什么也不做。在DEBUGU状态下,assert(_Expression)首先被替换成||表达式。根据||表达式的规则首先计算(!!(_Expression))的值,如果为true,||后面的表达式不会做计算。如果为false,将会计算后面的表达式。然而,后面的表达式是一个_wassert函数调用,对应的参数为_Expression对应的字条串,assert所在的文件名,及行号。


mingw的_wassert函数实现如下:

[cpp]  view plain  copy
  1. extern int mingw_app_type;  
  2.       
  3. void __cdecl _wassert(const wchar_t *_Message,const wchar_t *_File,unsigned _Line)  
  4. {  
  5.     wchar_t *msgbuf = (wchar_t *) malloc (8192*sizeof(wchar_t));  
  6.   
  7.     if (!_File || _File[0] == 0)  
  8.         _File = L"<unknown>";  
  9.   
  10.     if (!_Message || _Message[0] == 0)  
  11.         _Message = L"?";  
  12.   
  13.     _snwprintf (msgbuf, 8191,  
  14.         L"Assertion failed!\n\nFile: %ws, Line %u\n\nExpression: %ws",  
  15.         _File,_Line, _Message);  
  16.   
  17.     if (mingw_app_type == 0)  
  18.         fwprintf (stderr, L"%ws\n", msgbuf);  
  19.     else  
  20.         OutputDebugStringW(msgbuf);  
  21.   
  22.     abort ();  
  23. }  

显然,上面的实现不难。msbuf中存放的就是要打印的输出。根据不同的app类型,输出方式不一样。如果是普通的命令行方式,输出到stderr。如果是图形应用,估计会跳出一个窗口吧!程序最后会调用一个abort,结束程序。当然,进程都结束了,msbuf会自动释放,没必要手工释放了。


Interesting!!

猜你喜欢

转载自blog.csdn.net/snailcpp/article/details/79850336