C multilinea macro: do / while (0) vs blocco portata [duplicato]
Domanda
possibili duplicati:
Qual è l'uso di do while (0) quando si definisce una macro?
Perché a volte ci sono Do insignificante / while e if / else in macro C / C ++?
do {...} while (0) ciò che è buono per?
Ho visto alcune macro C multilinea che sono avvolti all'interno di un do / while (0) ciclo come:
#define FOO \ do { \ do_stuff_here \ do_more_stuff \ } while (0)
Quali sono i vantaggi (se presenti) di scrivere il codice in questo modo invece di utilizzare un blocco di base:
#define FOO \ { \ do_stuff_here \ do_more_stuff \ }
Soluzione
http://bytes.com/groups/c/ 219.859-do-while-0-macro-sostituzioni
Andrey Tarasevich:
L'intera idea di usare 'fare / mentre' versione è quello di fare una macro che sarà espandersi in una dichiarazione regolare, non in un'istruzione composta. Questo è fatto in modo da rendere l'uso della funzione di stile macro uniforme con la Uso delle funzioni normali in tutti i contesti.
Si consideri il seguente schizzo codice
if (<condition>)
foo(a);
else
bar(a);
dove 'foo' e 'bar' sono funzioni ordinarie. Ora immaginate che ti sentiresti desidera sostituire la funzione 'foo' con una macro della natura sopra
if (<condition>)
CALL_FUNCS(a);
else
bar(a);
Ora, se la macro è definita in accordo con il secondo approccio (Solo '{' e '}') il codice non sarà più la compilazione, perché il 'vero' ramo di 'se' è ora rappresentata da un'istruzione composta. E quando si mettere un ';' Dopo questa istruzione composta, è finito tutto il 'se' dichiarazione, orfano in tal modo il ramo 'altro' (da qui l'errore di compilazione).
Un modo per risolvere il problema è quello di ricordare di non mettere ';' dopo macro "invocazioni"
if (<condition>)
CALL_FUNCS(a)
else
bar(a);
Questo compilerà e funzionano come previsto, ma questo non è uniforme. Il soluzione più elegante è quella di fare in modo che la macro espandersi in un regolare un'affermazione, non in un composto uno. Un modo per raggiungere questo obiettivo è quello di definire la macro come segue
#define CALL_FUNCS(x) \
do { \
func1(x); \
func2(x); \
func3(x); \
} while (0)
Ora, questo codice
<*>verrà compilato senza problemi.
Si noti tuttavia la piccola ma importante differenza tra la mia definizione
di CALL_FUNCS
e la prima versione nel messaggio. Non ho messo un
;
dopo } while (0)
. Mettere un while (0)
al termine di tale definizione
avrebbe immediatamente sconfiggere l'intero punto di utilizzo di 'fare / po' e fare
che macro più o meno equivalente alla versione composto-dichiarazione.
Non so il motivo per cui l'autore del codice che ha citato nel tuo originale messaggio di mettere questo <=> dopo <=>. In questa forma entrambe le varianti sono equivalente. L'idea che sta dietro all'uso 'fare / mentre' la versione non è includere questa finale <=> nella macro (per i motivi che ho spiegato sopra).