VC 中预处理指令与宏定义的妙用(2)

ZDNet软件频道 时间:2002-07-09 作者:刘巍 |  我要评论()
本文关键词:
在上一篇文章中,我演示了几个常用的宏定义和预处理指令,但可以说这些都是相当常规的技巧。下面要介绍的宏定义与预处理指令的用法也是ATL,MFC以及LINUX中使用得比较多的非常重要的技巧。
LINUX的怪圈

在刚开始阅读LINUX的时候有一个小小的宏让我百思不得其解:

#define wait_event(wq,condition)

do{

if(condition)

              break;

       __wait_event(wq,condition);

}while(0)

这是一个奇怪的循环,它根本就只会运行一次,为什么不去掉外面的dowhile结构呢?我曾一度在心里把它叫做“怪圈”。原来这也是非常巧妙的技巧。在工程中可能经常会引起麻烦,而上面的定义能够保证这些麻烦不会出现。下面是解释:

假设有这样一个宏定义

#define macro(condition)

if(condition) dosomething();

现在在程序中这样使用这个宏:

if(temp)

       macro(i);

else

       doanotherthing();

一切看起来很正常,但是仔细想想。这个宏会展开成:

if(temp)

       if(condition) dosomething();

else

       doanotherthing();

这时的else不是与第一个if语句匹配,而是错误的与第二个if语句进行了匹配,编译通过了,但是运行的结果一定是错误的。

为了避免这个错误,我们使用dowhile(0) 把它包裹起来,成为一个独立的语法单元,从而不会与上下文发生混淆。同时因为绝大多数的编译器都能够识别dowhile(0)这种无用的循环并进行优化,所以使用这种方法也不会导致程序的性能降低。


百度大联盟认证黄金会员Copyright© 1997- CNET Networks 版权所有。 ZDNet 是CNET Networks公司注册服务商标。
中华人民共和国电信与信息服务业务经营许可证编号:京ICP证010391号 京ICP备09041801号-159
京公网安备:1101082134