抠下VS2008里assert的实现
来源:互联网 发布:代聊都用什么软件 编辑:程序博客网 时间:2024/05/16 23:33
自己一直不怎么用assert,主要是因为以前感觉貌似assert不是标准里提供的,而是特定编译器提供的
刚才查了查C语言他爸那本书,
原来在附录里提到了assert
B.6部分
(直接拷贝文字,中文字符乱码,所以拷贝了图片)
查了查VS2008中具体实现
如下:
#define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )
注意,这个地方_wasser这个w是因为VS2008中工程默认字符集为Unicode,即宽字符集
!!(_Expression)
两个感叹号的做法在某些地方常见到,比较巧妙
作用为把各种值转为0或者1
比如!!5 == 1
!!0 == 0
具体实现为
#ifdef _UNICODEvoid __cdecl _wassert ( const wchar_t *expr, const wchar_t *filename, unsigned lineno )#else /* _UNICODE */void __cdecl _assert ( const char *expr, const char *filename, unsigned lineno )#endif /* _UNICODE */{ /* * Build the assertion message, then write it out. The exact form * depends on whether it is to be written out via stderr or the * MessageBox API. */ if ( (_set_error_mode(_REPORT_ERRMODE)== _OUT_TO_STDERR) || ((_set_error_mode(_REPORT_ERRMODE) == _OUT_TO_DEFAULT) && (__app_type == _CONSOLE_APP)) ) {#ifdef _UNICODE { TCHAR assertbuf[ASSERTBUFSZ]; HANDLE hErr ; DWORD written; hErr = GetStdHandle(STD_ERROR_HANDLE); if(hErr!=INVALID_HANDLE_VALUE && hErr!=NULL) { if(swprintf(assertbuf, ASSERTBUFSZ,_assertstring,expr,filename,lineno) >= 0) { if(GetFileType(hErr) == FILE_TYPE_CHAR) { if(WriteConsoleW(hErr, assertbuf, (unsigned long)wcslen(assertbuf), &written, NULL)) { abort(); } } } } }#endif /* _UNICODE */ /* * Build message and write it out to stderr. It will be of the * form: * Assertion failed: <expr>, file <filename>, line <lineno> */ if ( !anybuf(stderr) ) /* * stderr is unused, hence unbuffered, as yet. set it to * single character buffering (to avoid a malloc() of a * stream buffer). */ (void) setvbuf(stderr, NULL, _IONBF, 0); _ftprintf(stderr, _assertstring, expr, filename, lineno); fflush(stderr); } else { int nCode; TCHAR * pch; TCHAR assertbuf[ASSERTBUFSZ]; TCHAR progname[MAX_PATH + 1]; /* * Line 1: box intro line */ _ERRCHECK(_tcscpy_s( assertbuf, ASSERTBUFSZ, BOXINTRO )); _ERRCHECK(_tcscat_s( assertbuf, ASSERTBUFSZ, dblnewline )); /* * Line 2: program line */ _ERRCHECK(_tcscat_s( assertbuf, ASSERTBUFSZ, PROGINTRO )); progname[MAX_PATH] = _T('\0'); if ( !GetModuleFileName( NULL, progname, MAX_PATH )) _ERRCHECK(_tcscpy_s( progname, MAX_PATH + 1, _T("<program name unknown>"))); pch = (TCHAR *)progname; /* sizeof(PROGINTRO) includes the NULL terminator */ if ( (sizeof(PROGINTRO)/sizeof(TCHAR)) + _tcslen(progname) + NEWLINESZ > MAXLINELEN ) { pch += ((sizeof(PROGINTRO)/sizeof(TCHAR)) + _tcslen(progname) + NEWLINESZ) - MAXLINELEN; _ERRCHECK(_tcsncpy_s( pch, (MAX_PATH + 1) - (pch - progname), dotdotdot, DOTDOTDOTSZ )); } _ERRCHECK(_tcscat_s( assertbuf, ASSERTBUFSZ, pch )); _ERRCHECK(_tcscat_s( assertbuf, ASSERTBUFSZ, newline )); /* * Line 3: file line */ _ERRCHECK(_tcscat_s( assertbuf, ASSERTBUFSZ, FILEINTRO )); /* sizeof(FILEINTRO) includes the NULL terminator */ if ( (sizeof(FILEINTRO)/sizeof(TCHAR)) + _tcslen(filename) + NEWLINESZ > MAXLINELEN ) { size_t p, len, ffn; pch = (TCHAR *) filename; ffn = MAXLINELEN - (sizeof(FILEINTRO)/sizeof(TCHAR)) - NEWLINESZ; for ( len = _tcslen(filename), p = 1; pch[len - p] != _T('\\') && pch[len - p] != _T('/') && p < len; p++ ); /* keeping pathname almost 2/3rd of full filename and rest * is filename */ if ( (ffn - ffn/3) < (len - p) && ffn/3 > p ) { /* too long. using first part of path and the filename string */ _ERRCHECK(_tcsncat_s( assertbuf, ASSERTBUFSZ, pch, ffn - DOTDOTDOTSZ - p )); _ERRCHECK(_tcscat_s( assertbuf, ASSERTBUFSZ, dotdotdot )); _ERRCHECK(_tcscat_s( assertbuf, ASSERTBUFSZ, pch + len - p )); } else if ( ffn - ffn/3 > len - p ) { /* pathname is smaller. keeping full pathname and putting * dotdotdot in the middle of filename */ p = p/2; _ERRCHECK(_tcsncat_s( assertbuf, ASSERTBUFSZ, pch, ffn - DOTDOTDOTSZ - p )); _ERRCHECK(_tcscat_s( assertbuf, ASSERTBUFSZ, dotdotdot )); _ERRCHECK(_tcscat_s( assertbuf, ASSERTBUFSZ, pch + len - p )); } else { /* both are long. using first part of path. using first and * last part of filename. */ _ERRCHECK(_tcsncat_s( assertbuf, ASSERTBUFSZ, pch, ffn - ffn/3 - DOTDOTDOTSZ )); _ERRCHECK(_tcscat_s( assertbuf, ASSERTBUFSZ, dotdotdot )); _ERRCHECK(_tcsncat_s( assertbuf, ASSERTBUFSZ, pch + len - p, ffn/6 - 1 )); _ERRCHECK(_tcscat_s( assertbuf, ASSERTBUFSZ, dotdotdot )); _ERRCHECK(_tcscat_s( assertbuf, ASSERTBUFSZ, pch + len - (ffn/3 - ffn/6 - 2) )); } } else /* plenty of room on the line, just append the filename */ _ERRCHECK(_tcscat_s( assertbuf, ASSERTBUFSZ, filename )); _ERRCHECK(_tcscat_s( assertbuf, ASSERTBUFSZ, newline )); /* * Line 4: line line */ _ERRCHECK(_tcscat_s( assertbuf, ASSERTBUFSZ, LINEINTRO )); _ERRCHECK(_itot_s( lineno, assertbuf + _tcslen(assertbuf), ASSERTBUFSZ - _tcslen(assertbuf), 10 )); _ERRCHECK(_tcscat_s( assertbuf, ASSERTBUFSZ, dblnewline )); /* * Line 5: message line */ _ERRCHECK(_tcscat_s( assertbuf, ASSERTBUFSZ, EXPRINTRO )); /* sizeof(HELPINTRO) includes the NULL terminator */ if ( _tcslen(assertbuf) + _tcslen(expr) + 2*DBLNEWLINESZ + (sizeof(INFOINTRO)/sizeof(TCHAR)) - 1 + (sizeof(HELPINTRO)/sizeof(TCHAR)) > ASSERTBUFSZ ) { _ERRCHECK(_tcsncat_s( assertbuf, ASSERTBUFSZ, expr, ASSERTBUFSZ - (_tcslen(assertbuf) + DOTDOTDOTSZ + 2*DBLNEWLINESZ + (sizeof(INFOINTRO)/sizeof(TCHAR))-1 + (sizeof(HELPINTRO)/sizeof(TCHAR))))); _ERRCHECK(_tcscat_s( assertbuf, ASSERTBUFSZ, dotdotdot )); } else _ERRCHECK(_tcscat_s( assertbuf, ASSERTBUFSZ, expr )); _ERRCHECK(_tcscat_s( assertbuf, ASSERTBUFSZ, dblnewline )); /* * Line 6, 7: info line */ _ERRCHECK(_tcscat_s(assertbuf, ASSERTBUFSZ, INFOINTRO)); _ERRCHECK(_tcscat_s(assertbuf, ASSERTBUFSZ, dblnewline )); /* * Line 8: help line */ _ERRCHECK(_tcscat_s(assertbuf, ASSERTBUFSZ, HELPINTRO)); /* * Write out via MessageBox */ nCode = __crtMessageBox(assertbuf, _T("Microsoft Visual C++ Runtime Library"), MB_ABORTRETRYIGNORE|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL); /* Abort: abort the program */ if (nCode == IDABORT) { /* raise abort signal */ raise(SIGABRT); /* We usually won't get here, but it's possible that SIGABRT was ignored. So exit the program anyway. */ _exit(3); } /* Retry: call the debugger */ if (nCode == IDRETRY) { _DbgBreak(); /* return to user code */ return; } /* Ignore: continue execution */ if (nCode == IDIGNORE) return; } abort();}
- 抠下VS2008里assert的实现
- vs2008里的#include " "
- assert宏的实现
- assert宏的实现
- ASSERT的简易实现
- JMeter 下Javascript实现assert的注意点
- Android项目中的assert文件下的html里的js交互
- 简述C++里assert的使用
- assert的实现原理浅析
- assert增强宏的实现
- VS2008下的CAtlRegExp
- vs2008和QT及VTK实现三维重建之VS2008下QT的安装使用
- VS2008、QT及VTK实现DICOM图像三维重建之二:VS2008下VTK的安装使用
- 关于VS2008里的VC9使用点滴
- vs2008引用不了App_Code里的类
- VS2008里的代码如何格式化?
- 简述C++里assert的使用(转载)
- 简述C++里assert的使用(转)
- 2014百度校招PC客户端研发笔试题(西安站)
- 2014百度校招移动终端类笔试题(西安站)
- 百度2014校园招聘客户端开发笔试题(南京站)
- java中|和||的区别
- eclipse 下cocos2d-x游戏环境搭建及编译与运行
- 抠下VS2008里assert的实现
- 用户登入界面保存用户名和密码
- AutoMaper
- C++数据的封装和类体内定义成员函数的学习笔记
- oracle判断一个字符型日期是否在指定范围内
- Linq中Union与Contact方法用法对比
- 哥德巴赫猜想近似证明问题
- 开始的开始
- ASP.Net 页面鼠标点击处出现自定义菜单 实现示例