为什么在宏定义中使用do {} while(0)?

可能重复:
为什么在C / C ++宏中有时会出现无意义的do / while和if / else语句?

我遇到了如下代码:

#define ev_io_init(ev,cb,fd,events) \ do { \ ev_init ((ev), (cb)); \ ev_io_set ((ev),(fd),(events)); \ } while (0) 

我想知道为什么作者在这里使用do { } while (0) 。 这有什么不同吗?

 #define ev_io_init(ev,cb,fd,events) { \ ev_init ((ev), (cb)); \ ev_io_set ((ev),(fd),(events)); \ } 

BTW:代码来自libev,ev_local.h

考虑if( something ) function1(); else function2(); if( something ) function1(); else function2();

如果function1()实际上是一个宏,只需使用{ }要求你在使用点省略分号,但是do { } while(0)允许你使用与真实函数完全相同的语法。

(根本不使用任何类型的块构造只会生成完全破坏的代码,natch)

用循环包含代码允许预处理程序指令执行多个语句而不“破坏”if-else-constructs。 考虑以下:

 #define DO_SOMETHING() a();b();c(); void foo() { // This is ok... DO_SOMETHING(); } void bar() { // ...whereas this would trigger an error. if (condition) DO_SOMETHING(); else blah(); } 

第二个例子打破了if-else-construct,因为三个语句后跟一个else子句。 为了允许它正确替换, DO_SOMETHING的指令应该用do { ... } while(0)括起来。

do{}while(0)允许你从循环中断:

 do{ expr1; foo(); if ( cond ) break; expr2; goo(); } while (0); 

它与简单的块{...}相同,只是你可以在需要break语句时中断执行。 你不能在一个简单的代码块中这样做,除非你有多个检查,这可能会很麻烦。 由于条件为while(0) ,它仍然会被执行一次。