Qual é a utilidade de fazer while (0) quando definimos uma macro?

Duplicar Possível:
Declarações Do-While e if-else em macros C / C ++

Estou lendo o kernel do Linux e encontrei muitas macros como esta:

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

Por que eles usam isso em vez de defini-lo simplesmente em {}?

Você pode segui-lo com um ponto-e-vírgula e fazê-lo parecer e agir mais como uma function. Ele também funciona com if / else cláusulas corretamente então.

Sem o while (0), seu código acima não funcionaria com

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

já que o ponto-e-vírgula após a macro “comeria” a cláusula else, e o acima não compilaria.

Ele permite agrupar várias instruções em uma macro.

Suponha que você fez algo como:

 if (foo) INIT_LIST_HEAD(bar); 

Se a macro foi definida sem o encapsulamento de {…} while (0) ;, o código acima seria expandido para

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

Isso claramente não é o que se pretendia, já que apenas a primeira declaração será executada, se for mantida. A segunda declaração seria executada independentemente de se foo é válido.

Editar: Mais explicações em http://c-faq.com/cpp/multistmt.html e http://developer.apple.com/documentation/DeveloperTools/gcc-4.0.1/cpp/Swallowing-the-Semicolon.html # Engolir o ponto-e-vírgula