2009-05-13 15 views
6

Ich möchte den C Präprozessor bekommen, um Makros für mich zu erzeugen (d. H. Ich benutze nur C99). Ich hätte gerne ein MakroMakro-produzierende Makros in C?

#define make_macro(in) <...magic here...> 

schreiben und wenn ich

setzen
make_macro(name1) 
make_macro(name2) 

später im Code, würde es

#define name1(...) name1_fn(name1_info, __VA_ARGS__) 
#define name2(...) name2_fn(name2_info, __VA_ARGS__) 

erweitern und ich würde dann in der Lage sein name1 zu verwenden und name2 als (Makro-implementierte) Funktionen. Ich denke, dass ich in beiden Schritten Makros verwende: Es macht Sinn, ein Makro zu verwenden, um eine Vorlage wiederholt zu füllen, und die variadische Argumentbehandlung funktioniert nur über ein Makro.

Also was geht in die < ... Magie hier ...> Platzhalter, um dies zu tun? An diesem Punkt beginne ich zu glauben, dass es in C99 nicht möglich ist, aber vielleicht fehlen mir einige Details der Syntax.

+0

Warum ein Makro? Ich bekomme dies nicht, um eine Vorlage "wiederholt zu füllen". Welche Vorlage und welche Nachfüllung? –

Antwort

5

Es ist nicht möglich, in Standard C

1

#define make_macro(name,...) name##_fn(name##_info, __VA_ARGS__) Versuchen.

Verwendung wie folgt aus:

make_macro(name1) 
make_macro(name2,1) 

und dies würde

name1_fn(name1_info) 
name2_fn(name2_info,1) 
3

Es ist nicht möglich erzeugen, da das Makro nur einmal durchgeführt wird.

Dies bedeutet nicht, dass Sie nicht andere Makros in Ihrem Makro verwenden könnte, aber man konnte

#define TEST #define HALLO 33 

int x = TEST; 

und erwarten x 33 danach werden nicht! Was würden Sie erhalten, ist ein Syntaxfehler, weil Sie

versucht
int x = #define HALLO 33; 

Oder vielleicht der Compiler beschwert sich bereits über #define in #define.

3

Haben Sie überlegt, M4-Makros zu verwenden? Ich denke, dass sie auf den meisten Plattformen verfügbar sind, so dass dies keine Einschränkung sein sollte.

M4 GNU page

+1

+1, M4 wird oft übersehen und ist ein sehr leistungsfähiges Code-Generator-Tool. Ich wünschte, die Leute würden jedes Mal, wenn sie mich sehen, mit den LISP-Witzen aufhören. –

1

Wie jeder gesagt hat, kann man nicht genau das tun, was Sie fordern.

Sie könnten in der Lage sein, so etwas zu tun, indem Sie die C preprocesor zwingt zweimal ausführen kann, beispielsweise mit einer Regel wie diese in der Make-Datei:

.c.pp: 
    $(CPP) $< -o [email protected] 

Dann die Dateien die Erweiterung von test.pp geben . Das Makefile wird es einmal ausführen, um die C-Datei zu generieren, und die normale Ausführung der C-Datei wird es dann ein zweites Mal ausführen.

Persönlich würde ich lieber ein externes Skript in Perl oder etwas schreiben, um den C-Code für mich zu generieren; es ist ein bisschen sauberer als Spiele mit dem C-Pre-Prozessor zu spielen. Es hängt davon ab, über wie viel Code wir sprechen.

+0

clever, aber ich habe das Gefühl, läuft CPP auf der Ausgabe von CPP kann Probleme mit Linien wie ein Pragmas und Zeilennummern verursachen. – Michael

1

Per C99 Section 6.10.3.2:

Jede # Vorverarbeitung Token in der Ersatzliste für eine funktionsähnliche Makro soll werden durch einen Parameter, der als nächste Vorverarbeitung Token in der Ersatzliste gefolgt.

So könnte man sicherlich eine #define in einem Makro setzen, wenn Sie einen Parameter namens define haben, aber es wird nie tun, was Sie sich wünschen. Das nervt mich oft, da ich in C arbeiten muss und daher keine C++ - Vorlagen verwenden kann.