do while(0)在宏定义中的应用

这是一个奇怪的循环,它根本就只会运行一次,为什么不去掉外面的do{..}while结构呢?我曾一度在心里把它叫做“怪圈”。

原来这也是非常巧妙的技巧。

在工程中可能经常会引起麻烦,而上面的定义能够保证这些麻烦不会出现。

下面是解释:

假设有这样一个宏定义

#define macro(condition) /

if(condition) dosomething()

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

if(temp)

macro(i);

else

doanotherthing();

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

if(temp)

if(condition) dosomething();

else

doanotherthing();

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

为了避免这个错误,我们使用do{….}while(0) 把它包裹起来,成为一个独立的语法单元,从而不会与上下文发生混淆。

同时因为绝大多数的编译器都能够识别do{…}while(0)这种无用的循环并进行优化,所以使用这种方法也不会导致程序的性能降低。

另一个讲解

这是为了含多条语句的宏的通用性

因为默认规则是宏定义最后是不能加分号的,分号是在引用的时候加上的

比如定义了一个宏fw(a,b),那么在c文件里一定是这样引用
fw(a,b);

如果不用do...while,那么fw就得定义成:

#define fw(a,b) {read((a));write((b));}   

那这样fw(a,b);展开后就成了:

{read(a);write(b);};

最后就多了个分号,这是语法错误

而定义成do...while的话,展开后就是:

do{read(a);write(b);}while(0);  完全正确

所以要写一个包含多条语句的宏的话,不用do...while是不可能的

一见钟情 发表于09-08 14:00 浏览65535次
分享到:

已有0条评论

暂时还没有回复哟,快来抢沙发吧

添加一条新评论

只有登录用户才能评论,请先登录注册哦!

话题作者

一见钟情
一见钟情(大校)
金币:1529个|学分:3659个
立即注册
畅学电子网,带你进入电子开发学习世界
专业电子工程技术学习交流社区,加入畅学一起充电加油吧!

x

畅学电子网订阅号