注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

时间记录器

记录我的Linux、Android学习之路

 
 
 

日志

 
 

do { ... } while(0)  

2012-10-25 21:39:56|  分类: C语言相关 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

Why do a lot of #defines in the kernel use do { ... } while(0)?

There are a couple of reasons:

  • (from Dave Miller) Empty statements give a warning from the compiler so this is why you see #define FOO do { } while(0).

    空的宏定义,编译器会给warning。

  • (from Dave Miller) It gives you a basic block in which to declare local variables.

    代码块,可以声明局部变量。

  • (from Ben Collins) It allows you to use more complex macros in conditional code. 

    在有条件判断的地方可以应用稍微复杂点的宏定义。

    Imagine a macro of several lines of code like:

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

    Now imagine using it like:

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

    This interprets to:

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

    As you can see, the if then only encompasses the printf(), and the do_something_useful() call is unconditional (not within the scope of the if), like you wanted it. So, by using a block like do { ... } while(0), you would get this:

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

    Which is exactly what you want.

  • (from Per Persson)  多个语句时候 分号 也可能引发错误

    As both Miller and Collins point out, you want a block statement so you can have several lines of code and declare local variables. But then the natural thing would be to just use for example:

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

    However that wouldn't work in some cases. The following code is meant to be an if-statement with two branches:

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

    But it would be interpreted as an if-statement with only one branch:

    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(); 

    The problem is the semi-colon (;) coming directly after the block. The solution for this is to sandwich the block between do and while (0). Then we have a single statement with the capabilities of a block, but not considered as being a block statement by the compiler. Our if-statement now becomes:

    if (x > y)         do {                 int tmp;                 tmp = x;                 x = y;                 y = tmp;         } while(0); else         do_something(); 
  • (from Bart Trojanowski) gcc adds Statement-Expressions which provide an alternative to the do-while-0 block. They provide the above mentioned benefits and are slightly more legible.

    #define FOO(arg) ({         \            typeof(arg) lcl; \            lcl = bar(arg);  \            lcl;             \     }) 
  评论这张
 
阅读(204)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017