曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 4970|回复: 2
打印 上一主题 下一主题

宏与分号

[复制链接]

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
跳转到指定楼层
楼主
发表于 2009-11-5 20:35:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
如果留心的话,可以看到 linux内核代码经常有这么奇怪的宏定义:
#define wait_event(wq, condition)                                 
do {                        
         if (condition)  
                 break;
         __wait_event(wq, condition);
} while (0)
上面的宏中,while(0) 后是没有分号的,而且这个宏的 do 里执行一次,那为什么要这么定义呢?

这是因为,在程序里使用宏时,我们按照会在语句的后面加个分号 ; ,如:
wait_event(wq,conditon);
展开后,成为:
do {                        
         if (condition)  
                 break;
         __wait_event(wq, condition);
} while (0);
由此可见,分号自己加上了。假如在宏定义中已在 while(0) 后添加了分号。那么对于在程序中,单独的调用这个宏,不管在宏的后面是否添加分号,那都是可以的;如果是添加了分号,那就是执行了一个空语句。

但是对于 if  ... else ... 结构,情况就不一样了,像下面的程序:
#include <stdio.h>

int condition = 0;

#define wait_condition         \
do {                \
    if (condition == 10)    \
        break;        \
    condition++;        \
    sleep(1);        \
} while (0);            \

int main()
{
     int k = 1;

     if (k == 1)
         wait_condition;       /*添加了分号编译会报错*/
     else
         printf ("hello world\n");

     printf ("%d\n", condition);

     return (0);
}
编译报错
[beyes@localhost programming]$ gcc -g temp.c -o temp.exe
temp.c: 在函数‘main’中:
temp.c:19: 错误:‘else’没有对应的‘if’
如果在程序中将 wait_condition;后的分号去掉,那就可以编译通过了,但这看上去就不符合 C 语言的表达式习惯。所以,在宏定义里的 while(0) 后不需要添加分号。
然而,不管宏里加不加分号,但在程序里如下使用,也不会出现问题:
{wait_condition; }
将宏语句用大括号括起来,这样整个宏将被当成一个整体看待,所以也是正确的。

0

主题

1

帖子

4

积分

初学弟子

积分
4
沙发
发表于 2010-11-13 15:39:00 | 只看该作者
原因是,这样做会让程序的看起来更加简洁清晰(在程序中使用大括号把一个单独的宏括起来多少总觉得有些碍眼)。

这个可不是。。。

有时候你的宏 包含多条语句的时候:
你可能会写

if (condition)
        macro;

如果没有 do ... while(0)
的话, macro 除了第一个语句之外的 其它语句都会被执行到。

其它的一些功能, 感兴趣可以去搜索一下。

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
板凳
 楼主| 发表于 2010-11-16 09:55:56 | 只看该作者

回 1楼(pynux) 的帖子

如果没有 do ... while(0)
的话, macro 除了第一个语句之外的 其它语句都会被执行到。
可否详细说一下?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-5-10 05:31 , Processed in 0.085944 second(s), 21 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表