Pregunta

Ambos macro expansión y amp; La generación de código tiene pros y amp; contras. ¿Cuál es tu enfoque favorito y por qué? ¿Cuándo debemos elegir uno sobre el otro? Por favor, amablemente asesorar. ¡Gracias!

La expansión de macros puede ser muy útil & amp; servicial: http://dtemplatelib.sourceforge.net/table.htm

vs

Mientras que la generación de código te da un montón de código agradable: http://code.google.com/p/protobuf/ http://incubator.apache.org/thrift/

¿Fue útil?

Solución

Es una compensación. Déjame dar un ejemplo. Me topé con la técnica de ejecución diferencial alrededor de 1985, y creo que es una muy buena Herramienta para la programación de 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 mucks con la estructura de control como esta:

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 buena manera de hacerlo sería escribir un analizador 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 para C, C ++, o lo que sea?

Entonces, en lugar de eso, 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 del código a mano. Este es un dolor real, pero aún así vale la pena en comparación con la forma habitual de codificar estas cosas.

Otros consejos

Para c ++, prefiero la metaprogramación de plantillas o la generación de código sobre macros, pero las macros todavía tienen sus usos.

El ejemplo que ha dado con dbtemplatelib podría estar cubierto con c ++ 0x Variadic Plantillas , con beneficios adicionales como la comprobación de tipos, etc.

En C o C ++, la expansión de macros 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 idiomas Lisp, la expansión de macro es la generación de código, son exactamente lo mismo. Para escribir una macro, escribe un programa (en Lisp) para transformar la entrada de la expresión S en otra expresión S, que luego se pasa al compilador.

Ambos tienen sus problemas. A diferencia de las macros, la generación de código puede producir código legible y que se puede depurar (¿es eso incluso una palabra?), Pero es menos flexible y más difícil de cambiar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top