Mehrzeilige Präprozessor-Makros


79

Wie erstelle ich ein mehrzeiliges Präprozessor-Makro? Ich weiß, wie man eine Zeile macht:

#define sqr(X) (X*X)

aber ich brauche so etwas:

#define someMacro(X)
    class X : public otherClass
    {
         int foo;
         void doFoo();
    };

Wie kann ich das zum Laufen bringen?

Dies ist nur ein Beispiel, das echte Makro kann sehr lang sein.


Sie können die Antwort leicht erhalten, indem Sie die SO durchsuchen. zB stackoverflow.com/questions/4007865/…
Forever Learner

Verschiedene Methoden sind hier: parashift.com/c++-faq/macros-with-multi-stmts.html
Ayrat

Antworten:


122

Sie verwenden \als Zeilenfortsetzungs-Escapezeichen.

#define swap(a, b) {               \
                       (a) ^= (b); \
                       (b) ^= (a); \
                       (a) ^= (b); \
                   }

BEARBEITEN: Wie @abelenky in den Kommentaren hervorhob, muss das \Zeichen das letzte Zeichen in der Zeile sein . Ist dies nicht der Fall (auch wenn es sich danach nur um Leerzeichen handelt), werden in jeder Zeile danach verwirrende Fehlermeldungen angezeigt.


44
Ein Wort der Vorsicht: Stellen Sie sicher, dass \ das letzte Zeichen in der Zeile ist. In C spielt das Leerzeichen normalerweise keine Rolle, aber in diesem Fall können unsichtbare Leerzeichen am Ende der Zeile Sie töten.
Abelenky

2
Man sollte jedoch hinzufügen, dass der resultierende Text in einer Zeile steht. Da C alle Leerzeichen zwischen Token gleich behandelt, spielt es normalerweise keine Rolle, aber dennoch.
Peter - Wiedereinsetzung Monica

Eine andere Sache, die ich vorschlagen würde, ist, ` after all useful lines of the macro, and add a comment afterward saying something like // nach dem Makro . It's sometimes easier to ensure that all lines of a macro end with `eine leere Zeile zu platzieren, als sicherzustellen, dass alle bis auf die letzte Zeile dies tun.
Supercat

Ich wusste nicht, dass Sie das bitweise x oder so verwenden können, um Variablen auszutauschen, aber ich wünschte, ich hätte es gedacht !!!
Cmarangu

18

Sie können festlegen, dass ein Makro mehrere Zeilen umfasst, indem Sie \am Ende jeder Zeile einen Backslash ( ) einfügen :

#define F(x) (x)   \
              *    \
             (x)

18

BITTE BEACHTEN SIE, wie Kerrek SB und Coaddict betonten, worauf in der akzeptierten Antwort hingewiesen werden sollte, setzen Sie IMMER geschweifte Klammern um Ihre Argumente. Das sqr-Beispiel ist das einfache Beispiel, das in CompSci-Kursen vermittelt wird.

Hier ist das Problem: Wenn Sie es so definieren, wie Sie es getan haben, was passiert, wenn Sie "sqr (1 + 5)" sagen? Sie erhalten "1 + 5 * 1 + 5" oder 11
Wenn Sie die Klammern richtig platzieren, erhalten #define sqr(x) ((x)*(x))
Sie ((1 + 5) * (1 + 5)) oder was wir wollten 36 ... schön.

Ed S. wird das gleiche Problem mit 'Swap' haben


wie wäre es mit sqr(++i) ? (Angenommen, wir haben eine int i) :)
Géza Török

Ich habe es als Übung gemacht und anscheinend iwird es erhöht, wenn es in das Makro eingesetzt wird (in diesem Fall wird es zweimal ersetzt), dann wird es multipliziert. Alsosqr(++5) == ((7) * (7))
jiveturkey

2
@ GézaTörök Die Erweiterung von sqr(++i)to ((++i)*(++i))würde undefiniertes Verhalten hervorrufen, weil der Wert voni innerhalb dieser Anweisung mehr als einmal geändert wird (kein Sequenzpunkt zwischen den Operationen).
Moooeeeep

5

Sie müssen die neue Zeile am Ende der Zeile umgehen, indem Sie sie mit einem \:

#define sqr(X) \
        ((X)*(X))
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.