Question

Les deux Macro expansion & amp; La génération de code a des avantages & amp; les inconvénients. Quelle est votre approche préférée et pourquoi? Quand devrions-nous choisir l'un sur l'autre? S'il vous plaît veuillez conseiller. Merci!

L’expansion des macros peut être très pratique & amp; utile: http://dtemplatelib.sourceforge.net/table.htm

vs

Alors que la génération de code vous donne plein de bons codes: http://code.google.com/p/protobuf/ http://incubator.apache.org/thrift/

Était-ce utile?

La solution

C'est un compromis. Laissez-moi vous donner un exemple. Je suis tombé sur la technique de la exécution différentielle vers 1985, et je pense que c'est une très bonne outil de programmation d'interfaces utilisateur. En gros, il faut des programmes simples et structurés comme ceci:

void Foo(..args..){
  x = y;
  if (..some test..){
    Bar(arg1, ...)
  }
  while(..another test..){
    ...
  }
  ...
}

et muck avec la structure de contrôle comme ceci:

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;}
  ...
}

Maintenant, un très bon moyen de le faire aurait été d’écrire un analyseur syntaxique pour C ou quel que soit le langage de base, puis de parcourir l’arbre d’analyse syntaxique en générant le code que je souhaite. (Quand je l'ai fait à Lisp, cette partie était facile.)

Mais qui veut écrire un analyseur syntaxique en C, C ++ ou autre?

Donc, au lieu de cela, je viens d’écrire des macros pour pouvoir écrire le code comme suit:

void deFoo(..args..){
  PROTECT(x = y);
  IF(..some test..)
    deBar(PROTECT(arg1), ...)
  END
  WHILE(..another test..)
    ...
  END
  ...
}

Cependant, lorsque je fais cela en C #, quelqu'un dans leur sagesse a décidé que les macros étaient mauvaises, et je ne veux pas écrire un analyseur C #, je dois donc générer le code à la main. C’est une douleur royale, mais cela en vaut quand même la peine par rapport à la manière habituelle de coder ces choses.

Autres conseils

Pour c ++, je préfère la métaprogrammation de modèles ou la génération de code aux macros, mais les macros ont toujours leur utilité.

L'exemple que vous avez donné avec dbtemplatelib pourrait être traité avec c ++ 0x Variadic Modèles , avec des avantages supplémentaires tels que la vérification de type, etc.

En C ou C ++, il est notoirement difficile de déboguer l’expansion de macros. En revanche, écrire un générateur de code est plus facile à déboguer car il s’agit d’un programme séparé.

Cependant, sachez qu’il ne s’agit que d’une limitation du pré-processeur C. Par exemple, dans la famille de langages Lisp, l’expansion de macros correspond à la génération de code , c’est exactement la même chose. Pour écrire une macro, vous écrivez un programme (en Lisp) pour transformer l’entrée d’expression S en une autre expression S, qui est ensuite transmise au compilateur.

Les deux ont leurs problèmes. Contrairement aux macros, la génération de code peut produire un code lisible et débogable (est-ce même un mot?), Mais il est moins flexible et plus difficile à modifier.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top