可能的重复:
C/C++ 宏中的 Do-While 和 if-else 语句
do { ... } while (0) — 它有什么用?
我正在阅读 linux 内核,发现很多这样的宏:
#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)
为什么他们使用它而不是简单地在 {} 中定义它?
可能的重复:
C/C++ 宏中的 Do-While 和 if-else 语句
do { ... } while (0) — 它有什么用?
我正在阅读 linux 内核,发现很多这样的宏:
#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)
为什么他们使用它而不是简单地在 {} 中定义它?
你可以在它后面加上一个分号,让它看起来和行为更像一个函数。它也适用于 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.html和http://developer.apple.com/documentation/DeveloperTools/gcc-4.0.1/cpp/Swallowing-the-Semicolon.html的进一步解释#吞下分号