先列一下我手头的资料:
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 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 sam