Frage zu (etwas konstruiertem) Macro-Problem
-
Hallo,
ich habe folgenden Code:#define USE_HEAP #ifdef USE_HEAP #define make_array(Name, size) unsigned *Name = new unsigned[size] #else #define make_array(Name, size) unsigned Name[size] #endif //... make_array(a, 10); a[0]=1; //...Dabei möchte ich das array mittels eines macros wieder freigeben
#ifdef USE_HEAP #define delete_array(Name) delete [] Name #else #define delete_array(Name) /*Mache Garnichts*/ #endifSodass folgender Code gültig ist, egal ob USE_HEAP definiert ist, oder nicht
make_array(a, 10); free_array(a);Ich weis, dass es ungefähr der blödsinnigste Weg ist, arrays zu erstellen (besser alles direkt aufn Heap, oder STL (vector) benutzen, oder in template funktionen kapseln...), aber mir geht es hier darum, die Funktionsweise von Macros zu verstehen.
Wie sage ich also "delete_array", dass es NICHTS machen soll, wenn USE_HEAP nicht definiert ist?
-
Du hast es richtig gemacht.
Beachte, daß es die leere Anweisung;gibt.
Und Deine Makro-Aufrufe müssen mit ; abgeschlossen werden. So wird ausdelete_array(foo);ganz richtig
;.
-
Obwohl das Macro ein "Argument" entegennimmt kannes also leer bleiben?
Das wusste ich nicht! Danke Volkard!
-
Ich habe oft gesehen dass es so gemacht wird:
#define MACRO_THAT_DOES_NOTHING(x) ((void)0)Vielleicht kann mir jmd. erklären was der Vorteil davon ist.
Gibt es mit ein potentielles Problem der "leeren" Version das durch((void)0)gelöst wird?EDIT: mir is grad selbst ein solches potentielles Problem eingefallen:
#include <stdio.h> //#define MACRO_THAT_DOES_NOTHING(x) #define MACRO_THAT_DOES_NOTHING(x) ((void)0) int main() { // würde mit der "leeren" Version nicht gehen MACRO_THAT_DOES_NOTHING(123), printf("test"); return 0; }
-
hustbaer schrieb:
Ich habe oft gesehen dass es so gemacht wird:
MACRO_THAT_DOES_NOTHING(123), printf("test");Ja, assert kann das in allen Implementierungen, die ich bisher sah.
Aber ich hab's auch noch nie so verwendet gesehen.
-
hustbaer schrieb:
Ich habe oft gesehen dass es so gemacht wird:
#define MACRO_THAT_DOES_NOTHING(x) ((void)0)Vielleicht kann mir jmd. erklären was der Vorteil davon ist.
Gibt es mit ein potentielles Problem der "leeren" Version das durch((void)0)gelöst wird?Auch Compiler-Warnungen können hier lästig werden. Man will, dass dies ein Statement ist. View Compiler würden ohne Code (auch wenn er wegoptimiert wird) bei einem if Statement eine Warung auswerfen:
if (something) MACRO_THAT_DOES_NOTHING(x);
-
volkard schrieb:
Und Deine Makro-Aufrufe müssen mit ; abgeschlossen werden.
Würde ich nicht ganz verallgemeinern. Wir verwenden im Projekt z.B. an ein paar Stellen Makros, die, damit sie (Bis auf die Großschreibung) konsistent zu dem restlichen Code "erscheinen" kein ";" enthalten (sondern explizit mit diesem beendet werden).
Ich würde aber auch niemals Makronamen so gestalten wie Funktionsnamen.
-
asc schrieb:
Würde ich nicht ganz verallgemeinern. Wir verwenden im Projekt z.B. an ein paar Stellen Makros, die, damit sie (Bis auf die Großschreibung) konsistent zu dem restlichen Code "erscheinen" kein ";" enthalten (sondern explizit mit diesem beendet werden).
Natürlich. Never ever ; im Makro. Sonst hat man hier probleme:
if(foo) MAKRO(); else bar();Aber das meinte Volkard ja auch nicht. Deshalb verwendet man ja den ((void)0) trick. ich habe manchmal auch eine leere Funktion noop() die ich für sowas einsetze...
Ich würde aber auch niemals Makronamen so gestalten wie Funktionsnamen.
kommt darauf an. viele makros sind ja normale Funktionen. zB max() in C. Man muss nur auf die Namenskollisionen aufpassen...