设为首页 加入收藏

TOP

C标准库源码解读(VC9.0版本)――assert.h(二)
2014-11-23 23:18:09 来源: 作者: 【 】 浏览:7
Tags:标准 源码 解读 VC9.0 版本 assert.h
部分,要求编译器实现处理,是在预编译期间展开的预定义宏。
_CRT_WIDE(x)宏是把x展开为L##String形式,也就是成为一个宽字节的字符串,无论传进去的是什么内容,都统统转为宽字节字符串。对于C语言中井号的用法,简单来说,#x是转换成”x“,也就是展开为字符串 ;L##x是转换成Lx,也就是展开成连接串。我们在VC的debug环境下一般断言语句为假的时候,会弹出一个提示窗口,这也是设计断言用于调试时候的目的。从这个方向看来,_wassert()函数就是跳出窗口的函数咯。
_wassert()在assert.c文件实现,由于代码中套了太多微软本身实现的宏和检测处理,一些该忽略的就不要关注。
[cpp]
#ifdef _UNICODE
void __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: , file , line
*/
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);
}
我们只看UNICODE版本的函数,_set_error_mode我们先忽略,后面_app_type指明:如果是控制台程序,并且取得标准错误句柄,就向控制台输出一些信息然后退出。可以看到,这个if里调用了几个函数,大写开头的全是WindowsAPI函数,里面的实现就不追究了;但其他的如swprintf, abort,setvbuf,_ftprintf,fflush,我们可以追踪其实现。等等,我们在实现assert呢!如果swprintf里面调用了assert了怎么办?在The C programming language里面P20:
A naive, way to write the active form of the macro is:
[cpp]
#define assert (test) i f ( ! (test) ) \
fprintf (stderr, "Assertion failed: %s, f i l e %s, line %i\nW, \
#test, __FILE__, __LINE__) /* UNACCEPTABLE! */
This form is unacceptable for a variety of reasons:The macro must not directly call any of the library output functions, suchas fprintf. Nor may it refer to the macro stderr. These names areproperly declared or defined only in the header . The programmight not have included that header, and the header mustnot. A program can define macros that rename any of the names fromanother header, provided it doesn't include that header. That mandatesthat the macro call a function with a secret nam
首页 上一页 1 2 3 4 下一页 尾页 2/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇[C和指针]不定参数 下一篇[Slackware]Build Broadcom 802.1..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: