while visual utilizar tag songs serie resueltos repeticion regulares preguntas numeros macro las habilitar funcion for expresiones ejercicios ejemplos disney dev con como ciclos ciclo canciones c++ macros

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.