当我们定义宏时,do while(0)有什么用?

时间:2009-05-29 00:05:13

标签: c macros linux-kernel

  

可能重复:
  Do-While and if-else statements in C/C++ macros

我正在阅读linux内核,我发现了很多像这样的宏:

#define INIT_LIST_HEAD(ptr) do { \
    (ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)

为什么他们使用这个而不是简单地在{}?

中定义它

2 个答案:

答案 0 :(得分:135)

您可以使用分号跟随它,使其看起来更像一个函数。 它也适用于if / else子句。

如果没有while(0),上面的代码将不适用于

if (doit) 
   INIT_LIST_HEAD(x);
 else 
   displayError(x);

因为宏之后的分号会“吃掉”else子句,而上面的内容甚至都不会编译。

答案 1 :(得分:42)

它允许您将多个语句组合成一个宏。

假设你做了类似的事情:

if (foo) 
    INIT_LIST_HEAD(bar);

如果在没有封装do {...} while(0);的情况下定义宏,则上面的代码将扩展为

if (foo)
    (bar)->next = (bar);
    (bar)->prev = (bar);

这显然不是预期的,因为如果foo成立,只会执行第一个语句。无论foo是否成立,第二个语句都将被执行。

修改:http://c-faq.com/cpp/multistmt.htmlhttp://developer.apple.com/documentation/DeveloperTools/gcc-4.0.1/cpp/Swallowing-the-Semicolon.html#Swallowing-the-Semicolon

的进一步说明