从一些经典代码中常常看到宏中使用do...while(0)的用法,感觉上do...while(0)只是在有可能要中途跳出后续一段代码的时候替换goto的一种用法,其他的就不求甚解了。

今天总算看到了wiki上对do...while(0)的解释,算是解了心中的一个疑惑。

一种情况是,这种用法可以避免在if/for下使用宏时,由于宏中的多个语句遗漏大括号而造成流程错误。就像下面这一段代码,可算是个明显的错误了。


  #define DO_SOMETHING()  DO_A();\
        DO_B();  \
        DO_C()
   
//

    if (CONDITION_A)
        DO_SOMETHING();


要是使用do...while(0)DO_SOMETHING()宏改成这样,就可以避免上述的错误了。

    #define DO_SOMETHING() do{ \
        DO_A(); \
        DO_B(); \
        DO_C(); \
    }
while(0)

这可就有一个疑问了,何必加上do...while(0)呢,直接使用大括号不就好了么?

不错,只要在宏中使用大括号就可以把多条语句合成一条语句了。不过,大括号并不是个天山雪莲般可治百病的灵药哟。

看看直接使用大括号的程序吧。

    #define DO_SOMETHING() {\
        DO_A();  \
        DO_B();  \
        DO_C();  \
    }

   
//

   
if (CONDITION_A())
        DO_SOMETHING();
   
else
        DO_SOMETHING_ELSE();

看出问题了么?由于if语句下的宏后多的那个小小的分号,if下的一个语句就变成了两个语句,随后的else可就会提示你语法错误喽

而使用之前do...while(0)的宏就不会有这个问题,这也就是do...while(0)的第二个用处了。

当然,以上说的这些都是一种无奈的保护机制。如果保持一个良好的编程习惯,比如在if和else后面紧跟大括号,就不需要在乎宏上的do...while(0)了。

只是,可惜的是,当我把do...while(0)使用到公司的代码中时,却发现这触犯了Lint工具的检测规范,而直接给了我违规的结论。无奈之下,只得把do...while(0)全部删除。

或许,Lint工具并不是告诉我这样做违反编程规范,只是想提醒我要养成良好的遵守编程习惯吧
posted on 2007-01-18 00:37  香依香偎孤旅独行的驿站  阅读(332)  评论(1编辑  收藏  举报