Duplicata possible:
instructions Do-While et if-else dans les macros C/C++
Je lis le noyau Linux et j'ai trouvé de nombreuses macros comme celle-ci:
#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)
Pourquoi utilisent-ils cela plutôt que de le définir simplement dans un {}?
Vous pouvez le suivre avec un point-virgule et le faire ressembler et agir plus comme une fonction. Il fonctionne également correctement avec les clauses if/else.
Sans le moment (0), votre code ci-dessus ne fonctionnerait pas avec
if (doit)
INIT_LIST_HEAD(x);
else
displayError(x);
puisque le point-virgule après la macro "mangerait" la clause else, et ce qui précède ne serait même pas compilé.
Il vous permet de regrouper plusieurs instructions dans une macro.
Supposons que vous ayez fait quelque chose comme:
if (foo)
INIT_LIST_HEAD(bar);
Si la macro a été définie sans l'encapsulage do {...} while (0) ;, le code ci-dessus s'étendrait jusqu'à
if (foo)
(bar)->next = (bar);
(bar)->prev = (bar);
Ce n'est clairement pas ce qui était prévu, car seule la première instruction sera exécutée si foo tient. La deuxième instruction serait exécutée, que foo soit ou non maintenu.
Edit: Plus d'explications sur http://c-faq.com/cpp/multistmt.html et http://developer.Apple.com/documentation/DeveloperTools/gcc-4.0. 1/cpp/Swallowing-the-Semicolon.html # Swallowing-the-Semicolon