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.

laute Katze
quelle
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
Siehe auch
Ciro Santilli 法轮功 冠状 病. 事件 法轮功

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.

Ed S.
quelle
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)
Kerrek SB
quelle
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

jiveturkey
quelle
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))
Codaddict
quelle