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 \
  }
È stato utile?

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top