先列一下我手头的资料:
1.The C Programming Language
2.The C Standar Library
3. Programming Language C 1988 http://flash-gordon.me.uk/ansi.c.txt
4. Rationale for International Standard—Programming Languages— C http://www.open-std.org/jtc1/sc22/wg14/www/docs/C99RationaleV5.10.pdf
这些都是原始的权威资料
目的:熟悉C语言库在windows下的实现原理,复习windows的API,期望达到精通C语言。
原则:从C的标准库的实现跟进到WindowsAPI函数,API底层进内核的部分就不属于讨论范围了。有疑问的C语言的语法和规定需要追踪到C标准的权威文档里。
先列举assert.h内容:
/***
*assert.h - define the assert macro
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
* Defines the assert(exp) macro.
* [ANSI/System V]
*
* [Public]
*
****/
#include <crtdefs.h>
#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;),编译能通过吗?如果能过汇编后是什么样子的?实践出真知,试试就知道了。
#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有如下内容:
3.8.8 Predefined macro names
The following macro names shall be defined by the implementation:
The line number of the current sourc