2009-11-27 6 views

Antwort

2

Es ist ein Kompromiss ist abgedeckt werden. Lassen Sie mich ein Beispiel geben. Ich bin ungefähr 1985 auf die Technik von differential execution gestoßen, und ich denke, es ist ein wirklich gutes Werkzeug für die Programmierung von Benutzeroberflächen. Grundsätzlich dauert es einfach strukturierte Programme wie folgt aus:

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

und mucks mit der Steuerstruktur wie folgt aus:

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

nun eine wirklich gute Möglichkeit, dies zu tun gewesen wäre, um einen Parser zu schreiben für C oder was auch immer die Basissprache ist, und gehen Sie dann den Syntaxbaum, um den gewünschten Code zu generieren. (Wenn ich es in Lisp gemacht habe, war dieser Teil einfach.)

Aber wer will einen Parser für C, C++ oder was auch immer schreiben?

Anstatt also, ich habe gerade Makros schreiben, so dass ich den Code so schreiben kann:

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

Allerdings, wenn ich dies in C# zu tun, jemand in ihrer Weisheit beschlossen Makros war schlecht, und ich don Ich möchte keinen C# Parser schreiben, also muss ich die Code-Generierung von Hand machen. Das ist ein königlicher Schmerz, aber es ist es immer noch wert, verglichen mit der üblichen Art, diese Dinge zu kodieren.

+0

+1 danke Mike. Das ist die beste Antwort :) – Viet

5

in C oder C++, Makroerweiterung ist notorisch schwer zu debuggen. Auf der anderen Seite ist das Schreiben eines Codegenerators einfacher zu debuggen, da es ein separates Programm ist.

Sie sollten jedoch beachten, dass dies lediglich eine Einschränkung des C-Präprozessors darstellt. Zum Beispiel in der Lisp-Familie von Sprachen, ist die Makroerweiterung Code-Generierung, sie sind genau das gleiche. Um ein Makro zu schreiben, schreiben Sie ein Programm (in Lisp), um die S-Ausdruck-Eingabe in einen anderen S-Ausdruck umzuwandeln, der dann an den Compiler übergeben wird.

+0

Danke für Ihre Antwort, Greg. Es braucht mehr Zeit, um einen anständigen Code-Generator zu schreiben und Makros sehen aus wie ein schneller Hack, um Dinge zu erledigen. – Viet

+0

++ Meine Gefühle genau. Es wäre schön, wenn es eine Möglichkeit gäbe, die Vorverarbeitung zu durchlaufen. Trotzdem bevorzuge ich Makros, wenn die Code-Generierung einfach genug ist. –

9

Für C++ bevorzuge ich entweder Vorlage Metaprogrammierung oder Code-Generierung über Makros, aber Makros haben noch ihre Verwendung.

Das Beispiel, das Sie mit dbtemplatelib gegeben haben könnte mit C++ 0x Variadic Templates, mit zusätzlichen Vorteilen wie Typ usw. Überprüfung

+0

Danke für Ihren Vorschlag. Vorlagen haben auch ihre Vorzüge. Variadic-Makros sind da, aber Variant-Schablonen sind noch populär, da C++ 0x noch neu ist. – Viet

+0

Nun, um genau zu sein, es ist noch nicht einmal out, und es wird eher ein "C++ 1x" sein. In einigen Compilern werden jedoch variantenspezifische Vorlagen implementiert. Um sie beispielsweise mit gcc zu verwenden, müssen Sie "-std = C++ 0x" als Compiler-Schalter hinzufügen. – hirschhornsalz

3

Beide haben ihre Probleme. Im Gegensatz zu Makros kann die Codegenerierung lesbaren und debugbaren Code (ist das sogar ein Wort?) Erzeugen, ist aber weniger flexibel und schwieriger zu ändern.

+0

+1. danke für die Antwort. – Viet