当我们定义一个macros的时候,(0)有什么用呢?

可能重复:
C / C ++macros中的Do-While和if-else语句

我正在读linux内核,并且发现了很多像这样的macros:

#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); 

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

它允许你将几个语句分组成一个macros。

假设你做了这样的事情:

 if (foo) INIT_LIST_HEAD(bar); 

如果macros定义没有封装do {…} while(0),则上面的代码将扩展为

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

这显然不是这个意思,因为如果foo成立,只有第一个陈述会被执行。 不pipefoo是否成立,第二个陈述都会被执行。

编辑:进一步的解释在http://c-faq.com/cpp/multistmt.html和http://developer.apple.com/documentation/DeveloperTools/gcc-4.0.1/cpp/Swallowing-the-Semicolon.html #吞咽最分号