下面这个DUMP_WRITE定义,使用了do...while(0):
#define DUMP_WRITE(addr,nr) do { memcpy(bufp,addr,nr); bufp += nr; } while(0)
do...while(0)是先执行后判断的,那这边使用这个的作用是什么?
do-while循环是先执行后判断循环条件。所以,这个定义意味着每当引用这个宏 操作时会执行循环体一次,而且只执行一次。可是,为什么要这样通过一个do-while循环来定义呢? 这似乎有点怪。我们不妨看看其它几种可能。首先,能不能定义成如下式样?
#define DUMP_WRITE(addr,nr) memcpy(bufp,addr,nr); bufp += nr;
不行。如果有一段程序在一个if语句中引用这个宏操作就会出问题,让我们通过一个假想的例子 来说明:
if(addr)
DUMP_WRITE(addr,nr);
else
do_something_else();
经过预处理以后,这段代码就会变成这样:
if(addr)
memcpy(bufp,addr,nr); bufp += nr; else
do_something_else();
你也许马上会想到要在定义中加上花括号,成为这样:
#define DUMP_WRITE(addr,nr) {memcpy(bufp,addr,nr); bufp += nr;}
可是,上面那段程序还是通不过编译,因为经过预处理就变成这样:
if(addr)
{memcpy(bufp,addr,nr); bufp += nr;}; else
do_something_else();
同样,gcc在碰到else前面的“;’’时就认为if语句已经结束,因而后面的else不在if语句中。相 比之下,采用do-while的定义在任何情况下都没有问题。
--------------------------------------------------------------------------
注:以上示例摘自《Linux内核源代码情景分析》