通常我们对C/C++中宏的理解不外乎两点:
一, 用来处理头文件的重复包含。
二, 用来定义类似的函数的宏。
对于第一点,这个大家都能很好理解。第二点:用来定义类似的函数的宏也常常见到,比较经典的是:
define max(a,b) (a>b)?(a):(b)
类似于这样的作法主要是想绕过类型检查,这样无论a和b是什么类型之要能用">"运算符来比较的便可以使用宏来代替反复写max函数不同版本。但这样做明显有一个问题:我们缺少了类型保护,这对于大型应用程序来说是非常恐怖的一件事。(但也不尽然)。
C++中引入了范型(Generic Method)来解决这个问题。
但我今天想表达的全然不是上面这些,C/C++中的宏还有一个用处:
代码生成器(Code Generator)
也许你对此不屑,坦白地讲先前我也是如此。这个很明显嘛,上学的时候我都知道了,比如上面的例子,当你写出如下的代码:
int iMax = max(5,6);
编译器会为你“自动”生成代码:
int iMax = (5>6)?(5):(6);
确实如此,编程三年以来,我确实也是这样的理解的。直到最近在看Graham Paul的《ANSI Common Lisp》,前言中有这样一句话:
Macros, for example: Lisp programmers can, and often do,
write programs to write their programs for them.
是的,We Can Write a Program
to program for us.
经此一提,抽象层次,思考方式转然一变:
是呀,我们可以写出一些程序,这些程序的作用是为我们写程序。
像绕口令?是有些
结合经验的话,我觉得VC/MFC的源码中经常会出现这种技术/思想的利用。刚开始我总不能理解为什么MFC的源码中总是会插入一些宏,有些宏还非常巨大。当时也觉得微软的这些程序员让人不可思议。现在我知道了:
对于他们(MFC的作者)来说,他们有时在写程序,有时却在写会帮助他们写程序的程序(宏)。
原来如此!
本篇只做提醒不做更深的介绍,有兴趣的可以:
一, 看看MFC的源码,找找哪些宏是Generic Method,哪些是Code Generator;
二, 去看看Graham Paul的《ANSI Common Lisp》;
三, 如果你足够强,可以看看Graham的《On Lisp》;
Jerry.Chou
12/17'08
阅读(1192) | 评论(0) | 转发(0) |