Domanda

Espansione sia macro che amp; La generazione del codice ha pro e amp; cons. Qual è il tuo approccio preferito e perché? Quando dovremmo scegliere l'uno rispetto all'altro? Si prega gentilmente di avvisare. Grazie!

L'espansione macro può essere molto utile & amp; utile: http://dtemplatelib.sourceforge.net/table.htm

vs

Mentre la generazione del codice ti dà un sacco di codice carino: http://code.google.com/p/protobuf/ http://incubator.apache.org/thrift/

È stato utile?

Soluzione

È un compromesso. Lasciami fare un esempio. Mi sono imbattuto nella tecnica di esecuzione differenziale intorno al 1985, e penso che sia davvero buono strumento per la programmazione delle interfacce utente. Fondamentalmente, ci vogliono semplici programmi strutturati come questo:

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

e muck con la struttura di controllo in questo modo:

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

Ora, un ottimo modo per farlo sarebbe quello di scrivere un parser per C o qualunque sia la lingua di base, e quindi camminare sull'albero di analisi, generando il codice che desidero. (Quando l'ho fatto a Lisp, quella parte è stata facile.)

Ma chi vuole scrivere un parser per C, C ++ o altro?

Quindi, invece, scrivo solo macro in modo da poter scrivere il codice in questo modo:

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

Tuttavia, quando lo faccio in C #, qualcuno nella loro saggezza ha deciso che le macro erano cattive e non voglio scrivere un parser C #, quindi devo fare la generazione del codice a mano. Questo è un dolore reale, ma ne vale ancora la pena rispetto al solito modo di codificare queste cose.

Altri suggerimenti

Per c ++ preferisco la metaprogrammazione dei modelli o la generazione di codice rispetto alle macro, ma le macro hanno ancora i loro usi.

L'esempio che hai fornito con dbtemplatelib potrebbe essere coperto con c ++ 0x Variadic Modelli , con vantaggi aggiuntivi come il controllo del tipo ecc.

In C o C ++, l'espansione delle macro è notoriamente difficile da eseguire il debug. D'altra parte, scrivere un generatore di codice è più facile da eseguire il debug perché è un programma separato in sé.

Tuttavia, dovresti essere consapevole che questa è solo una limitazione del preprocessore C. Ad esempio, nella famiglia di lingue Lisp, l'espansione delle macro è generazione di codice, sono esattamente la stessa cosa. Per scrivere una macro, scrivi un programma (in Lisp) per trasformare l'input S-expression in un'altra espressione S, che viene quindi passata al compilatore.

Entrambi hanno i loro problemi. A differenza delle macro, la generazione di codice può produrre codice leggibile e debuggable (è anche una parola?), Ma è meno flessibile e più difficile da modificare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top