宏定义使用小技巧
一般来讲,程序编译过程如下:预处理、编译、汇编和链接,一共四个阶段,其中宏展开位于第一个阶段,宏展开的最关键核心就是:字符串替代,原原本本的替代。
1. 获取结构体某元素的地址偏移量
#define OFFSET (type, field) ( (size_t) &( ((type*)0)->field ) )
ANSI C 允许任何值为0的常量被强制转换为任何一种类型的指针,但是转换结果是NULL指针
&( ((type*)0)->field )意图为计算当前结构体实例的收地址为0时field字段的地址
而我们聪明的编译器则根据type的内存布局和结构体首地址实例计算出常量(地址)
2. 五个预定义宏名(ANSI标准)
__LINE__ 及 __FILE__ 宏包含程序的当前行数和文件名。
__DATE__ 宏指令含有形式为月/日/年的串,表示源文件被翻译到代码时的日期。
__TIME__ 宏指令包含程序编译的时间。时间用字符串表示,其形式为: 分:秒
__STDC__ 宏指令的意义是编译时定义的。
可以定义宏,例如:
当定义了_DEBUG,输出数据信息和所在文件所在行
#ifdef _DEBUG
#define DEBUGMSG(msg,date) printf(msg);printf(“%d%d%d”,date,_LINE_,_FILE_)
#else
#define DEBUGMSG(msg,date)
#endif