Pourquoi utilise-t-on {} while (0) dans la définition de macro?

Dupliquer possible:
Pourquoi y a-t-il parfois des instructions do / while et if / else sans signification dans les macros C / C ++?

J’ai rencontré le code comme ci-dessous:

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

Je veux savoir pourquoi l’auteur utilise do { } while (0) ici. Y a-t-il une différence avec cela?

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

BTW: le code provient de libev, ev_local.h

Considérez if( something ) function1(); else function2(); if( something ) function1(); else function2();

Si function1() est en réalité une macro, le seul fait d’utiliser { } nécessite d’omettre le point-virgule au moment de l’utilisation, mais do { } while(0) permet d’utiliser exactement la même syntaxe que pour une fonction réelle.

(Ne pas utiliser de construction de bloc ne générerait que du code totalement cassé, natch)

Enfiler du code avec une boucle permet à une directive de préprocesseur d’exécuter plusieurs instructions sans “casser” les constructions if-else-. Considérer ce qui suit:

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

Le deuxième exemple casse la construction if-else-parce que trois instructions sont suivies d’une clause else . Pour lui permettre de se substituer correctement, les instructions de DO_SOMETHING doivent être jointes à un do { ... } while(0) .

Un do{}while(0) vous permet de sortir de la boucle:

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

C’est la même chose qu’un simple bloc {...} sauf que vous pouvez interrompre l’exécution quand vous voulez avec l’instruction break . Vous ne pouvez pas faire cela dans un simple bloc de code, sauf si vous avez plusieurs vérifications, ce qui peut devenir fastidieux. Il est toujours exécuté une fois, à cause de la condition while(0) .