2010-01-18 33 views

Respuesta

0

Esto es útil en ocasiones en un dominio muy cerrada para definir los pasos del proceso de una forma más legible:

void myfunc() { 
    DO_STEP_ONE; 
    THEN_ANOTHER_STEP; 
    KEEP_GOING; 
    LAST_STEP; 
} 

Pero por lo general sólo lo hace código más difícil de leer y entender.

A menos que valga la pena que los lectores de su código sepan lo que esos # define significan en detalle, y es una especie de atajo, simplemente logra que la gente busque en dos lugares para comprender una línea de código (arriba de archivo y en la función) en lugar de uno.

Rara vez uso este tipo de enfoque.

+0

usar macros para eso no es más legible que usar funciones con el mismo nombre – user463035818

0

Eso dependerá del lenguaje, compilador, etc, etc, etc ...

Sin embargo, no hay nada malo en ello, una vez como su nombre lo indica esas directivas se produce con anterioridad al proceso de compilación.

El pre-procesador elimina todas las referencias constantes por su valor real, toda la pseudo-función con el código adecuado, y así sucesivamente ...

0

Todos los problemas de la informática puede ser resueltos por otra nivel de indirección

Este es uno de estos niveles de indirección adicionales :-)

decir que en algún momento que la función necesita otro argumento o que no es necesario para llamarlo, puede cambiar el #define una vez en lugar de cambiar todos los lugares donde se está llamando a la función.

Útil para el desarrollo, pero peligroso para mantener el código de producción ... Ejecutaría el preprocesador para reemplazar esa regla una vez que tengo un código maduro y sé que no necesitaré cambiarlo.

+0

¿Qué tal tener demasiados niveles de indirección? ;) – daotoad

5

¿Un inconveniente? Por lo general, una definición de macro no termina en la tabla de símbolos del ejecutable. Un poco más difícil de depurar.

5

El problema es que los argumentos son re = evaluados cada vez que se utilizan:

#define MIN(A,B) ((A) < (B))?(A):(B); 

en cuenta que tengo para envolver todos los argumentos en '(' ')' para asegurarse de que la expresión se evalúa corectly . ¿Pero qué pasa si hacemos esto?

int s = MIN(++current,Max); 

Codificando esto, esperaría que la corriente se incrementara una vez antes de que se llame a la función.Pero debido a que es una macro que se incrementa una vez en la prueba y una segunda vez si todavía es menor que Max

+0

Si bien esto es una desventaja de las macros, 'gcc' proporciona * extensiones específicas del compilador * para solucionar esto:' #define MIN (a, b) ({typeof (a) _a = (a); typeof (b) _b = (b); _a <_b? _a: _b;}) '. – kennytm

+0

@Kenny: Tu Macro Foo es mejor que la mía. Lo intenté y funciona. Aunque no parecía que fuera así, no pensé que una declaración (Block) pudiera actuar como un valor. –

+0

@Kenny: Desafortunadamente, ni siquiera la extensión de gcc funcionaría si se llamara a 'MIN' sobre las variables que se llamaron inoportunamente' _a' y '_b'. – jamesdlin

2

Hay varios problemas que se pueda imaginar:

  • En C++ la macro no tiene espacio de nombres y alcance de clase, por lo que es el mismo en todas partes. Un ejemplo de esto son los desafortunados min y max define en algún lugar de windows.h. Si está programando para Windows e incluye windows.h y desea escribir std :: numeric_limits :: max(), entonces max será reemplazado por algún código ... Esto deja el código no disponible después de la ejecución del preprocesador. (De acuerdo, hay formas de desactivar macros min/max en windows.h, pero sigue siendo un diseño pobre!)
  • La macro no se puede depurar muy bien. El depurador se detendrá en la línea que la macro no se usa en el código dentro de la macro ...
  • Posible reevaluación de los parámetros de la macro (esto podría evitarse teniendo un bloque con variables locales dentro de la macro, pero esto haría que la depuración ¡aún peor!)
0

¿Por qué buscaría desventajas al usar un código de preprocesador específico? El uso de macros de preprocesador para cualquier otra cosa que no sea la compilación condicional (incluidos los resguardos incluidos) debe considerarse automáticamente incorrecta. La pregunta correcta es si hay ventajas para un uso particular.

Las macros de preprocesador no respetan el alcance o el uso de ninguna manera. Pueden estropear el código perfectamente bueno en formas inesperadas y difíciles de encontrar. Siempre evítelos a menos que tenga una buena razón para usar uno.

1

Bueno, si usted debe hacer eso (y hay algunas ocasiones cuando es posible), entonces al menos debe definir la macro como "-función como" de este modo: Código

#define SOME_FUNCTION() someFunction(defaultArgument) 

de lo contrario sería escribir que parecía una asignación por una constante cuando en realidad era una llamada a función; es decir;

x = SOME_FUNCTION ; // hidden function call 

pero con una macro "funciones como" que se vería obligado a escribir:

x = SOME_FUNCTION() ; // shorthand function-call with default argument 

Qué más ajustada a la sintaxis de pre-procesador con la sintaxis del lenguaje.

Por lo general, es mejor evitar las macros de función, pero algunas son más insidiosas que otras, esto de ninguna manera es el peor de los casos. Sin embargo, puede escribir fácilmente un contenedor de funciones en C, o en C++ usar un argumento predeterminado, y esto sería preferible en la mayoría de los casos.

0

Lo malo es que está ocultando el código. Lo bueno es que estás ocultando el código.

La desventaja suele ser mayor que la ventaja.

Por lo general, este enfoque en particular es bastante inútil y menos que la llamada se parece más a

someModule-> someStorage-> functionList [storage.getFunctionName] .pointer-> algunaFuncion (... argumento igualmente oscuro ...);

no tiene sentido hacerlo. Si solo el argumento es una llamada oscura, taquigrafía solo el argumento. Si solo es la función, taquigrafía solo la función.Si ambos, usted podría ser mejor con

SOME_FUNCTION(SOME_ARGUMENT); 

Si la función no se conoce con cualquier otra cosa, usted podría considerar quitarlo de la lista de argumentos y la obtención en el interior del cuerpo de la función. Y si el par se repite muy a menudo, en pequeñas variaciones, puede considerar funciones de envoltura.

Después de hacer varios errores en el código de una macro, aprenderá que es difícil depurarlos y no los usará de forma frívola.

Cuestiones relacionadas