web-dev-qa-db-fra.com

Quelle est l'utilité de do while (0) lorsque nous définissons une macro?

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 {}?

124
amazingjxq

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é.

138
SPWorley

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

42
rodion