Kurze Frage zu Makros
-
Moin,
ich wollte gern ein Makro schreiben, welches einige häufig verwendete Defines beinhaltet und sozusagen zu einem Makroblock zusammenfasst
ich möchte also gerne aus
#ifdef FLAG #define OTHER_FLAG //do something #undef OTHER_FLAG #endifetwas machen, dass ungefähr so aussieht
myflag //contains the #if and #define { //do something } //#undef #endifKann mir bitte jemand kurz beschreiben ob soetwas überhaupt geht und wie ich das definieren muss.
Danke!
-
Sowas?
#define DEBUG //Hier an- oder ausschalten #ifdef DEBUG #define ASSERT assert #else #ifdef MSVC #define ASSERT __assume #else //TODO: für andere compiler noch raussuchen #endif #endif
-
Wie wäre es damit, ganz/weitgehend auf Makros zu verzichten? Es gibt mit sehr großer Wahrscheinlichkeit eine bessere Lösung. Beschreib mal, was du warum erreichen möchtest, nicht wie du denkst, dies zu erreichen.
-
Das ist mal wieder das in meiner Signatur beschriebene XY-Problem. Zeig mal was du überhaupt erreichen willst.
-
ich wollte gern ein Makro schreiben, welches einige häufig verwendete Defines beinhaltet und sozusagen zu einem Makroblock zusammenfasst
Benutze einfach eine seperate Headerdatei, definiere jedes Makro einzeln und inkludiere diese Headerdatei bei Bedarf. Jedoch ist der Bedarf fuer Makros in gutem C++ sehr gering.
-
das ist schon das was ich haben möchte, es existieren in meiner Anwendung für bestimmte Abschnitte (etwa systemabhängiger code oder compilerflag-abhängiger code)ein define-block den ich gerne zur besseren übersicht statt in
#ifdef #define #define ... #undef #undef #endif1
blöcke einfach in ein makro packen möchte was diesen blöcken enspricht und am besten noch so aufgebaut ist
#define ANY_SYS_FLAG { /* user-code*/ } #ifdef ... #define ... #define ... /*user-code*/ #undef ... #undef ... #endifsodass ich anstelle konstrukt 1 zu verwenden einfach schreiben kann
//begin code block ANY_SYS_FLAG { //user-code here } //end of block
-
Mach's halt so?
SYS_FLAG_BEGIN { foo(); } SYS_FLAG_END
-
Ethon schrieb:
Mach's halt so?
Du kannst in Makros keine Makros ausführen.
#define FOO #define BAR bar FOO BAR
#define BAR bar BAR
-
SeppJ schrieb:
Ethon schrieb:
Mach's halt so?
Du kannst in Makros keine Makros ausführen.
#define FOO #define BAR bar FOO BAR
#define BAR bar BARdu meinst bestimmt eher definieren und nicht ausführen.
-
Ich verstehe.
Was ist dein Problem? Stört es dich so sehr, diese PP-Direktiven zu schreiben?
Ich muss dich aber leider enttäuschen. Sowas wie du willst, gibt es nicht - SeppJ hat's schon gesagt. Makros sind Makros, man kann keine Makros in Makros definieren lassen.
Daher kann man auch keine Abfolgen von Makros abkürzen.
Das was am ehesten noch ginge, wäre...- Die Makros in einen Header zu packen.
- Jedes mal vor dem kompilieren einen anderen Präprozessor, bspw. von dir geschrieben, drüberlaufen lassen, der bestimmte Ausdrücke ersetzt. Bei CodeBlocks bspw. kannste dir Pre/Post-Build Steps setzen und da so einen PP ablaufen lassen.
Ist aber natürlich ein Aufwand für nix und wieder nix.
... denn es ist doch nun wirklich nicht so schlimm, einfach deine Direktiven aus zuschreiben.
-
Sone schrieb:
Was ist dein Problem? Stört es dich so sehr, diese PP-Direktiven zu schreiben?
Ach was, ich mach das natürlich nur zum Spaß ...
Gerade folgende durchaus akzeptable Lösung gefunden
http://stackoverflow.com/questions/7372448/c-macro-to-conditionally-compile-code
-
Kannst du den jeweiligen, plattformspezifischen Code nicht einfach in eine Funktion packen? Möglicherweise sogar mit der selben Signatur für jede Plattform? Dann könntest du, anstatt kompliziert mit bedingter Kompilierung zu arbeiten, z.B. einfach die Implementierung der Funktion für jede Plattform in eine separate .cpp Datei packen und einfach je nach Plattform die entsprechende .cpp Datei nehmen...
-
Der Visual Studio Compiler kann auch folgendes
#if defined(HALLO) && defined(WELT) #endifAber auch mein Tip:
* Versuche Makros durch inline Funktionen zu ersetzen
* Nutze sonstige Präprozessor-Direktiven sparsam und weiseMakros sind einfache Ersetzungssysteme. Der Präprozessor geht ersetzt den Makro Aufruf einfach stur steif und dies führt zu Fehlern die sich ganz einfach vermeiden lassen.
#define min(A, B) A < B ? A : B int main(int argc, char** argv) { int a = 5; int b = 6; min(++a, b++)+1; // wird zu ++a < b++ ? ++a : b+++1; }
-
dot schrieb:
Kannst du den jeweiligen, plattformspezifischen Code nicht einfach in eine Funktion packen? Möglicherweise sogar mit der selben Signatur für jede Plattform? Dann könntest du, anstatt kompliziert mit bedingter Kompilierung zu arbeiten, z.B. einfach die Implementierung der Funktion für jede Plattform in eine separate .cpp Datei packen und einfach je nach Plattform die entsprechende .cpp Datei nehmen...
Das lohnt sich nicht wenn es sich dabei nur um kleine Abschnitte oder gar einzelne Funktionen handelt, etwa wenn der Endbenutzer eigenen Kontext hinzufügt. Dient auch nicht zuletzt der Lesbarkeit.
Ich glaube ich bin mit dem if-replace durchaus zufrieden
// Platform-Type als spezifische Definition im Projekt #ifdef Platform-Type_MyType //defined in a header #define PlatformName if(1) #else #define PlatformName if(0) #endifUnd später im Code und auch
int main(int argc, char** argv) { //do some stuff here //codeblock for my_sis my_sis { //do some mysis stuff here } //codeblock for my_sis with else my_sis { //do some mysis stuff here } else error_message //single statement for my_sis my_sis //do some mysis stuff here }Es kann mir keiner erzählen, dass das nicht übersichtlicher ist als ein block aus defines und gerade weil es sich dadurch nur um ein if replace handelt, kann ich innerhalb der klammern auch wieder defines setzen.
Problem ist natürlich, dass das nicht ausserhalb fvon Funktionscode platziert werden kann
-
Das größte Problem ist dass soetwas nicht gut geht:
WINDOWS_CODE { MessageBoxA(0, "Bla", ...); }Da zb. unter Linux der Compiler trotzdem auf den Inhalt das if-Blocks trifft (auch wenn der nicht erreichbar ist) und MessageBoxA nicht kennt.
static if müsste es endlich mal geben...
-
müsste der compiler das nicht wegoptimieren?
-
xamarin schrieb:
müsste der compiler das nicht wegoptimieren?
Was?
Es kann mir keiner erzählen, dass das nicht übersichtlicher ist als ein block aus defines
Nö. Aber wie willst du das erreichen?
-
Pria schrieb:
Es kann mir keiner erzählen, dass das nicht übersichtlicher ist als ein block aus defines
Nö. Aber beides ist unglaublich häßlich im Vergleich zu plattformspezifisch implelentierten Inlinefunktionen mit über die Plattformen hinweg gleicher Schnittstelle.
-
// Wird nicht ausgeführt #define ANY_SYS_FLAG if (false) // Wird dann ausgeführt #undef ANY_SYS_FLAG //begin code block ANY_SYS_FLAG { //user-code here } //end of block
-
Pria schrieb:
dot schrieb:
Kannst du den jeweiligen, plattformspezifischen Code nicht einfach in eine Funktion packen? Möglicherweise sogar mit der selben Signatur für jede Plattform? Dann könntest du, anstatt kompliziert mit bedingter Kompilierung zu arbeiten, z.B. einfach die Implementierung der Funktion für jede Plattform in eine separate .cpp Datei packen und einfach je nach Plattform die entsprechende .cpp Datei nehmen...
Das lohnt sich nicht wenn es sich dabei nur um kleine Abschnitte oder gar einzelne Funktionen handelt, etwa wenn der Endbenutzer eigenen Kontext hinzufügt. Dient auch nicht zuletzt der Lesbarkeit.
Wenn du mich fragst lohnt sich das gerade dann, denn sobald es um mehr als ein paar vereinzelte, unzusammenhängende Funktionen geht, heißt es sowieso die entsprechende Funktionalität in einer eigenen Komponente (Modul, Library etc.) kapseln. Dieser ganze Makro Kram ist jedenfalls Mist wenn du mich fragst. Nicht nur weil es hässlich ist wie die Nacht finster, sondern vor allem auch, weil der Code dadurch meiner Erfahrung nach sehr schnell sehr anstregend wird...
