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

可能的复制品:
C/C + + 宏中的 Do-While 和 if-else 语句
做{ ... }而(0)ーー它有什么好处?

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

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

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

58399 次浏览

您可以在它后面加上一个分号,使它看起来更像一个函数。 它还可以正确地处理 if/else 子句。

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

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

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

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

假设你做了这样的事:

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上的进一步解释