¿Por qué usar do {} while (0) en la definición de macro?

Posible duplicado:
¿Por qué a veces hay sentencias do / while y if / else en las macros C / C ++ sin sentido?

Conocí el código como abajo:

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

Quiero saber por qué el autor usa do { } while (0) aquí. ¿Hay alguna diferencia con esto?

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

Por cierto: el código es de libev, ev_local.h

Considera if( something ) function1(); else function2(); if( something ) function1(); else function2();

Si function1() es realmente una macro, solo usar { } requiere que omita el punto y coma en el punto de uso, pero do { } while(0) permite usar exactamente la misma syntax que para una función real.

(No usar ningún tipo de construcción de bloque en absoluto generaría un código completamente roto, natch)

El código adjunto con un bucle permite que una directiva de preprocesador ejecute varias declaraciones sin “romper” construcciones if-else. Considera lo siguiente:

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

El segundo ejemplo rompe la construcción if-else-porque tres sentencias son seguidas por una cláusula else . Para permitir que se sustituya correctamente, las instrucciones en DO_SOMETHING deben incluirse con un do { ... } while(0) .

A do{}while(0) permite interrumpir el ciclo:

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

Es lo mismo que un simple bloque {...} excepto que puede interrumpir la ejecución cuando lo desee con la instrucción break . No podría hacer eso en un bloque de código simple, a menos que tenga varias comprobaciones, lo que puede resultar engorroso. Todavía se ejecuta una vez, debido a la condición while(0) .