设为首页 加入收藏

TOP

C标准库源码解读(VC9.0版本)――assert.h(一)
2014-11-23 23:18:09 】 浏览:4593
Tags:标准 源码 解读 VC9.0 版本 assert.h
目的:熟悉C语言库在windows下的实现原理,复习windows的API,期望达到精通C语言
原则:从C的标准库的实现跟进到WindowsAPI函数,API底层进内核的部分就不属于讨论范围了。有疑问的C语言的语法和规定需要追踪到C标准的权威文档里。
先列举assert.h内容:
[cpp]
/***
*assert.h - define the assert macro
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
* Defines the assert(exp) macro.
* [ANSI/System V]
*
* [Public]
*
****/
#include
#undef assert
#ifdef NDEBUG
#define assert(_Expression) ((void)0)
#else
#ifdef __cplusplus
extern "C" {
#endif
_CRTIMP void __cdecl _wassert(_In_z_ const wchar_t * _Message, _In_z_ const wchar_t *_File, _In_ unsigned _Line);
#ifdef __cplusplus
}
#endif
#define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )
#endif /* NDEBUG */
ctrdefs.h包含了一些与系统和版本相关,以及部分结构体定义,在我们这里不关注。
NDEBUG宏是VC下Release与Debug版本的开关,常用VC环境的应该很清楚。
可以很清楚的看 到assert(_Expression)是一个宏,在Release版本下解析为((void)0)。这种写法,把0强制转换成空类型?平时编码的时候也很少看见。经过编译后看汇编执行,这一行没有在代码段里面,应该是被编译器直接过滤掉了。
由此,想到了一个问题:只有数字的表达式(如 1; 2;),编译能通过吗?如果能过汇编后是什么样子的?实践出真知,试试就知道了。
[cpp]
#ifndef _CRT_WIDE
#define __CRT_WIDE(_String) L ## _String
#define _CRT_WIDE(_String) __CRT_WIDE(_String)
#endif
再看Debug版本的展开。先判断(void)((!!(_Expression)),两个叹号,双重非语句,最终为true或false;就是说如果为true,assert语句在Debug下直接跳过。
__FILE__和__LINE__是文件名和当前行号。因为我看这些C标准库的目的就是向着“精通C语言”这几个在招聘条件里面经常列出来的技能,当然要追一下根底:__FILE__,__LINE___究竟——是不是C语言规定的内容?引用这篇文章:http://www.cnblogs.com/lixiaohui-ambition/archive/2012/08/21/2649052.html 这两个是C编译器内置宏。我再追根到了ANSI C的发布文档:http://flash-gordon.me.uk/ansi.c.txt有如下内容:
[plain]
3.8.8 Predefined macro names
The following macro names shall be defined by the implementation:
The line number of the current source line (a decimal constant). The
presumed name of the source file (a character string literal). The
date of translation of the source file (a character string literal of
the form Mmm dd yyyy , where the names of the months are the same as
those generated by the asctime function, and the first character of dd
is a space character if the value is less than 10). If the date of
translation is not available, an implementation-defined valid date
shall be supplied. The time of translation of the source file (a
character string literal of the form hh:mm:ss as in the time generated
by the asctime function). If the time of translation is not
available, an implementation-defined valid time shall be supplied.
the decimal constant 1./79/
The values of the predefined macros (except for __LINE__ and
__FILE__ ) remain constant throughout the translation unit.
None of these macro names, nor the identifier defined , shall be
the subject of a #define or a #undef preprocessing directive. All
predefined macro names shall begin with a leading underscore followed
by an upper-case letter or a second underscore.
上面内容列出了ANSI C要求编译器实现的预定义宏,包括行号、源文件名、指定格式的执行编译的日期、指定格式的执行编译的时间,并且__LINE__和__FILE__是在预编译时设置,日期时间在预编译期间是不转换展开的。
——那么,可以下结论:__FILE__和__LINE__是C语言标准的一
首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇[C和指针]不定参数 下一篇[Slackware]Build Broadcom 802.1..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目