134

可能的重复:
C/C++ 宏中的 Do-While 和 if-else 语句
do { ... } while (0) — 它有什么用?

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

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

为什么他们使用它而不是简单地在 {} 中定义它?

4

2 回答 2

149

你可以在它后面加上一个分号,让它看起来和行为更像一个函数。它也适用于 if/else 子句。

如果没有 while(0),您上面的代码将无法使用

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

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

于 2009-05-29T00:09:22.077 回答
44

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

假设你做了类似的事情:

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的进一步解释#吞下分号

于 2009-05-29T00:11:47.080 回答