Chinaunix首页 | 论坛 | 博客
  • 博客访问: 275575
  • 博文数量: 11
  • 博客积分: 2510
  • 博客等级: 少校
  • 技术积分: 837
  • 用 户 组: 普通用户
  • 注册时间: 2006-12-06 17:29
文章分类
文章存档

2011年(1)

2008年(10)

我的朋友

分类: LINUX

2008-05-06 00:32:01

FAQ/DoWhile0

为什么内核代码中大量的宏定义#define都使用do{...} while(0)?

有如下几个原因:
  •  (from Dave Miller) 对于空语句,编译器会报警告,这也就是你为什么常会看到#define FOO do{}while(0)
  •  (from Dave Miller) 可以在宏定义基本块中声明局部变量
  •  (from Ben Collins) 它使得我们可以在条件语句中使用更为复杂的宏定义,考虑包括如下代码的宏定义

#define FOO(x) \
        printf("arg is %s\n", x); \
        do_something_useful(x);


假设我们像下面这样使用它:

if (blah == 2)
        FOO(blah);


对宏进行扩展将得到

if (blah == 2)
        printf("arg is %s\n", blah);
        do_something_useful(blah);;


正如我们所看到的,if语句仅包括printf()语句,而do_something_useful()调用并没有包含在if语句的作用域
之中,即do_something_useful()语句将会无条件执行,而这并不是我们所期望的。因此,通过使用宏定义像do
{...}while(0)这样的代码块,我们将得到

if (blah == 2)
        do {
                printf("arg is %s\n", blah);
                do_something_useful(blah);
        } while (0);


上述宏定义扩展,也正是我们所需要的。
  • (from Per Persson) 正如Miller和Collins所提到的,我们需要这样一个语句块,它包括有多行代码并且声明了局部变量。  下来我们会很自然地如下示例来定义宏

#define exch(x,y) { int tmp; tmp=x; x=y; y=tmp; }


然而在有些情况下却不一定能够正常运行,下面是一个有两个分支的if语句代码示例:

if (x > y)
        exch(x,y); // Branch 1
else
        do_something()
// Branch 2


但是宏扩展之后,if语句将仅包含一个分支:

if (x > y) { // Single-branch if-statement!!!
        int tmp; // The one and only branch consists
        tmp = x; // of the block.
        x = y;
        y = tmp;
}
; // empty statement
else // ERROR!!! "parse error before else"
        do_something();


事实上,问题就出在if第一个分支代码块后的紧跟着的分号;。解决之道可以将宏定义块置于do和while(0)之

间。如此我们便拥有了一个单一的语句,但它却起着代码块的作用,而且编译器也不会将其作为代码块。于是

我们的if语句现在变为

if (x > y)
        do {
                int tmp;
                tmp = x;
                x = y;
                y = tmp;
        } while(0);
else
        do_something();

  • (from Bart Trojanowski) gcc增加了”语句-表达式“,它可以用于替代do-while-0方式,并且使用起来更为清楚简洁些。

#define FOO(arg) ({ \
           typeof(arg) lcl; \
           lcl = bar(arg); \
           lcl; \
    })

阅读(1389) | 评论(1) | 转发(0) |
0

上一篇:遇上爱

下一篇:内核FAQ之LikelyUnlikely

给主人留下些什么吧!~~

chinaunix网友2008-07-17 12:41:21

嗯,很好很强大。