Jaki jest pożytek z do while(0) gdy definiujemy makro? [duplikat]

to pytanie ma już odpowiedzi tutaj : Zamknięte 8 lat temu .

Możliwe duplikaty:
instrukcje Do-While I if-else w makrach C / C++
do { ... } while (0) - do czego to służy?

Czytam jądro Linuksa i znalazłem wiele makr takich jak:

#define INIT_LIST_HEAD(ptr) do { \
    (ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)

Dlaczego używają tego zamiast definiować to po prostu w {}?

Author: John Kugelman, 2009-05-29

2 answers

Możesz podążać za nim średnikiem i sprawić, że będzie wyglądał i działał bardziej jak funkcja. Działa również poprawnie z klauzulami if / else then.

Bez while(0) Twój powyższy kod nie działałby z

if (doit) 
   INIT_LIST_HEAD(x);
 else 
   displayError(x);

Ponieważ średnik po makrze "zjadłby" klauzulę else, a powyższa nie skompilowałaby się.

 142
Author: SPWorley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-29 00:09:22

Pozwala na grupowanie kilku instrukcji w jedno makro.

Załóżmy, że zrobiłeś coś takiego:

if (foo) 
    INIT_LIST_HEAD(bar);

Jeśli makro zostało zdefiniowane bez enkapsulującego do { ... } while (0);, powyższy kod rozszerzy się do

if (foo)
    (bar)->next = (bar);
    (bar)->prev = (bar);

To wyraźnie nie jest to, co było zamierzone, ponieważ tylko pierwsze polecenie zostanie wykonane, jeśli Foo utrzyma. Drugie polecenie będzie wykonywane niezależnie od tego, czy Foo posiada.

Edit: dalsze wyjaśnienie na http://c-faq.com/cpp/multistmt.html i http://developer.apple.com/documentation/DeveloperTools/gcc-4.0.1/cpp/Swallowing-the-Semicolon.html#Swallowing-the-Semicolon

 43
Author: rodion,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-29 00:17:07