que - C/C++ Expansión de macro vs. Generación de código
que es un macro en lenguaje c (4)
Ambos tienen sus problemas. A diferencia de las macros, la generación de código puede producir código legible y depurable (¿es eso una palabra?), Pero es menos flexible y más difícil de cambiar.
Tanto la expansión Macro como la generación de código tienen pros y contras. ¿Cuál es tu enfoque favorito y por qué? ¿Cuándo deberíamos elegir uno sobre el otro? Por favor, amablemente asesorar. ¡Gracias!
La expansión de macros puede ser muy útil y útil: http://dtemplatelib.sourceforge.net/table.htm
vs
Mientras que la generación de código le ofrece un buen código: http://code.google.com/p/protobuf/ http://incubator.apache.org/thrift/
En C o C ++, la expansión de macro es notoriamente difícil de depurar. Por otro lado, escribir un generador de código es más fácil de depurar porque es un programa separado en sí mismo.
Sin embargo, debe tener en cuenta que esto es simplemente una limitación del preprocesador C. Por ejemplo, en la familia de lenguajes Lisp, la expansión macro es generación de código, son exactamente lo mismo. Para escribir una macro, se escribe un programa (en Lisp) para transformar la entrada de S-expression en otra expresión S, que luego se pasa al compilador.
Es una compensación. Déjame dar un ejemplo. Me tropecé con la técnica de ejecución diferencial alrededor de 1985, y creo que es una herramienta realmente buena para programar interfaces de usuario. Básicamente, se necesitan programas estructurados simples como este:
void Foo(..args..){
x = y;
if (..some test..){
Bar(arg1, ...)
}
while(..another test..){
...
}
...
}
y se ensucia con la estructura de control así:
void deFoo(..args..){
if (mode & 1){x = y;}
{int svmode = mode; if (deIf(..some test..)){
deBar(((mode & 1) arg1 : 0), ...)
} mode = svmode;}
{int svmode = mode; while(deIf(..another test..)){
...
} mode = svmode;}
...
}
Ahora, una forma realmente buena de hacerlo habría sido escribir un analizador sintáctico para C o cualquiera que sea el idioma base, y luego recorrer el árbol de análisis, generando el código que quiero. (Cuando lo hice en Lisp, esa parte fue fácil).
Pero, ¿quién quiere escribir un analizador sintáctico para C, C ++ o lo que sea?
Entonces, en cambio, solo escribo macros para poder escribir el código así:
void deFoo(..args..){
PROTECT(x = y);
IF(..some test..)
deBar(PROTECT(arg1), ...)
END
WHILE(..another test..)
...
END
...
}
Sin embargo, cuando hago esto en C #, alguien en su sabiduría decidió que las macros eran malas, y no quiero escribir un analizador de C #, así que tengo que hacer la generación de código a mano. Es un dolor real, pero aún vale la pena en comparación con la forma habitual de codificar estas cosas.
Para c ++ prefiero la metaprogramación de plantillas o la generación de código sobre macros, pero las macros aún tienen sus aplicaciones.
El ejemplo que ha proporcionado con dbtemplatelib podría cubrirse con plantillas variables de c ++ 0x, con beneficios adicionales, como comprobación de tipos, etc.