c++ - visual - tag de las 20 preguntas
hacer mientras(falso) patrĂ³n (7)
Posible duplicado:
¿Por qué a veces hay sentencias do / while y if / else en las macros C / C ++ sin sentido?
¿Por qué es necesario do while(false)
en las siguientes macros?
#define LOG(message, ...) /
do { /
Lock<MutualExclusion> lock (logMutex); /
.... a lot of code ...
} while (false)
No creo que sirva para ningún propósito funcional. ¿Estoy pasando por alto algo?
Así que te ves obligado a agregar un punto y coma al final de la macro, cuando la usas. Este es un idioma común y la única forma de imponerlo.
Convierte un bloque en una sola declaración. Si solo usa un bloque (es decir, el código incluido en {}
) pueden suceder cosas extrañas, por ejemplo
#define STUFF() /
{ do_something(); do_something_else(); }
if (cond)
STUFF();
else
//...
el punto y coma extra rompe la sintaxis. El do {} while(false)
lugar es una sola declaración.
Puede encontrar más información sobre este y otros trucos de macro here .
La gente lo usa porque, de lo contrario, puedes arruinar tu if con declaraciones compuestas. Imagina
#define hai int x; /
x = 0;
if (condition)
hai;
else
func();
Imagina cómo es la fuente preprocesada.
if (condition)
int x;
x = 0;
else
func();
Oh, espera, ahora nuestro otro no funciona.
Sin embargo, las macros como esa son típicamente innecesarias en C ++.
La razón de esta práctica extraña en # define es encapsular las diferentes asignaciones dentro de un bucle que se ejecuta exactamente una vez, por lo que uno puede usar la macro como una función. Por ejemplo, con el código que publicaste, puedes escribir:
if(...)
LOG(x, y);
else
// Something else
y se expande como
if(...)
do {...} while(false);
else
// Something else
Esto no funcionaría sin el do ... while (falso) que rodea las diferentes asignaciones, porque eso se expandiría como
if(...)
Lock<MutualExclusion> lock (logMutex);
// Other code... Outside the if statement!
También forzar un punto y coma después de que la macro haga que parezca una función y no obtendrá errores porque agregó un punto y coma después de una función normal.
Me parece que solo se usa para reglas de alcance, por lo que Lock<MutualExclusion>
queda fuera del alcance al final del bloque.
Si esa es la razón para ello, entonces es completamente innecesario:
// some other code...
string s = "oh hai";
{
Lock<MutualExclusion> lock(logMutex);
// MAGIC HAPPENS
}
s = "oh bai";
Proporciona alcance local a lo que está dentro de la macro.
Si alguien tiene código que hace esto:
if (something)
LOG("My log message");
Eso se expandiría a:
if (something)
Lock<MutualExclusion> lock (logMutex);
// A bunch of other code
Lo cual es incorrecto (solo la primera línea estaría debajo de la sentencia if).
La macro se asegura de que la llamada a la macro esté dentro de un bloque de código.