6 votes

Expansion de macro C/C++ vs. Génération de code

À la fois l'expansion de macro & la génération de code ont des avantages & des inconvénients. Quelle est votre approche préférée et pourquoi ? Quand devrions-nous choisir l'un plutôt que l'autre ? Veuillez bien conseiller. Merci!

L'expansion de macro peut être très pratique & utile: http://dtemplatelib.sourceforge.net/table.htm

vs

Alors que la génération de code vous donne beaucoup de code intéressant: http://code.google.com/p/protobuf/ http://incubator.apache.org/thrift/

9voto

hirschhornsalz Points 16306

Pour le c ++, je préfère soit la méta-programmation de modèles, soit la génération de code par rapport aux macros, mais les macros ont toujours leurs utilisations.

L'exemple que vous avez donné avec dbtemplatelib pourrait être couvert avec c ++ 0x Modèles variadiques, avec des avantages supplémentaires comme la vérification des types, etc.

5voto

Greg Hewgill Points 356191

En C ou C++, l'expansion des macros est notoirement difficile à déboguer. D'un autre côté, l'écriture d'un générateur de code est plus facile à déboguer car c'est un programme séparé en soi.

Cependant, vous devez savoir que c'est simplement une limitation du préprocesseur C. Par exemple, dans la famille de langages Lisp, l'expansion des macros est la génération de code, ce sont exactement la même chose. Pour écrire une macro, vous écrivez un programme (en Lisp) pour transformer une entrée S-expression en une autre S-expression, qui est ensuite transmise au compilateur.

3voto

Nemanja Trifunovic Points 17239

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.

2voto

Mike Dunlavey Points 25419

C'est un compromis. Laissez-moi donner un exemple. J'ai découvert la technique de l'exécution différentielle vers 1985, et je pense que c'est un outil vraiment efficace pour la programmation des interfaces utilisateur. Fondamentalement, cela prend des programmes structurés simples comme ceci:

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

et manipule 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, une bonne manière de faire aurait été d'écrire un analyseur syntaxique pour le C ou pour le langage de base, puis parcourir l'arbre syntaxique pour générer le code que je veux. (Quand je l'ai fait en Lisp, cette partie était facile.)

Mais qui veut écrire un analyseur syntaxique pour le C, le C++, ou quoi que ce soit d'autre?

Alors, au lieu de cela, j'écris simplement des macros pour pouvoir écrire le code de cette manière:

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

Cependant, lorsque je le fais en C#, quelqu'un a décidé que les macros étaient mauvaises, et je ne veux pas écrire un analyseur pour le C#, donc je dois générer le code manuellement. C'est une vraie douleur, mais ça en vaut toujours mieux que la façon habituelle de coder ces choses.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X