内核中一些宏操作的定义

来源:互联网 发布:windows develop 编辑:程序博客网 时间:2024/05/22 11:58

#define DUMP_WRITE(addr,nr) do { memcpy(bufp,addr,nr); bufp += nr; } while(0)

读者想必知道,do-while循环是先执行后判断循环条件。所以这个定义意味着每次引用这个宏操作是会执行循环体一次,而且只执行一次,可是,为什么要这样通过一个do-while循环来定义呢?这似乎有点怪。我们不妨看看其他几种可能。首先,能不能改成如下式样?
00163: #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();
编译这段代码时gcc会失败,并报告语法错误。因为gcc认为if语句在memcpy()以后就结束了,然后却又碰到了一个else。如果把DUMP_WRITE()和do_something_else()换一下位置,编译倒是可以通过,问题却更严重了,因为不管条件满足与否bufp += nr都会得到执行。
读者马上会想到要在定义中加上括号,成为这样:
00163: #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的定义在任何一种情况下都没有问题。

0 0