免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 855 | 回复: 0
打印 上一主题 下一主题

内核FAQ之DoWhile0 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-05-06 00:32 |只看该作者 |倒序浏览

                                                                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;             \
    })
               
               
               
               
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/27708/showart_676938.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP