2016-07-30 25 views
0

Ich habe das Makro folgen:Wie Makro schreiben, um zu vermeiden, neu zu definieren?

#define my_add_property(ret, name, value) \ 
    object tmp; \ 
    tmp = *value; \ 
    add_property(ret, name, &tmp); 

Jetzt benutze ich das Makro in der Follow-Funktion:

void func() { 
    object *ret; 
    my_add_property(ret, "key", my_func1()); 
    my_add_property(ret, "value", my_func2()); 
} 

Es hat make error: tmp neu definiert wird.

Deshalb möchte ich object tmp##name verwenden, aber wenn der Name "key" ist, wird tmp##nametmp"key" sein. Ich sollte tun, wie schreibe das Makro, das machen tmp##name zu tmpkey nicht tmp"key"? Vielen Dank!

+2

Ich liebe es, wie die Leute aus gehen ihrer Art, Code schwer zu lesen und zu pflegen. Mögen sie ein hartes Leben? –

+2

Ist 'return' als Name eines Parameters eine gute Idee? –

+0

Warum nicht einfach 'add_property (ret," key ", my_func1())' '? Ein Zeiger auf "tmp" wird bedeutungslos, sobald 'func()' beendet ist. Was ist der Sinn von 'my_add_property()' an erster Stelle? Vielleicht, was Sie wirklich wollen, ist: 'object * tmp = malloc (sizeof (object)); * tmp = * Wert; add_property (ret, name, tmp) '? – user172818

Antwort

4

Sie können einen neuen Bereich in Ihrem Makro erstellen, so dass tmp nur für eine kurze Zeit leben wird durch die Umsetzung in einem do {} while(0) Verpackung, zum Beispiel:

#define my_add_property(return, name, value) do { \ 
    object tmp;         \ 
    tmp = *value;        \ 
    add_property(return, name, &tmp); } while(0) 
+4

Die übliche Form ist '#define MACRO (args) do {etwas; } while (0) '. Auf diese Weise werden Sie keine bösen Überraschungen erleben, wenn Sie sich nach "if"/"else"/"while"/"for" für Klammern entscheiden, und Sie erhalten etwas bessere Fehlermeldungen, wenn Sie solche Makros in einem Ausdruck verwenden . Nichtsdestoweniger gibt es keinen Grund, stattdessen eine "statische Inline" -Funktion zu verwenden. –

+0

@Rhymoid Vielen Dank, du hast recht! – thinkerou

+0

@slugonamission Vielen Dank, es ist OK. – thinkerou