为什么在宏定义中使用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)
,它仍然会被执行一次。