Verwenden Sie \, um jeden Zeilenumbruch, der Teil des Makros sein soll, zu umgehen.
Seien Sie sich jedoch bewusst, dass die Verwendung von Makros wie diesem die Struktur verbergen kann, wenn Sie nicht vorsichtig sind. Nehmen wir Ihr Beispiel:
if (bar)
FOOBAR();
else
do_something_else();
Raten Sie mal, worauf das hinausläuft. Wahrscheinlich nicht das, was Sie denken. Hier ist, was der Compiler sieht (Einrückung angepasst):
if (bar)
if (foo)
{
[Bar fooBar];
}
;
else
do_something_else();
Huch! Das Semikolon ist eine separate, leere Aussage. Jede if
benötigt nur eine Anweisung; die erste if
ist die zweite Aussage des if
und die zweite if
Die Anweisung der Kommission ist die zusammengesetzte Anweisung ( {…}
), so dass sie beide ihre Quote erfüllt haben, wobei das Semikolon weggelassen wurde.
Das Semikolon ist also nicht an eine if
-Sie ist bedingungslos. Das führt zu einem Syntaxfehler, wenn Sie dann versuchen, die else
zu einer unbedingten Aussage.
Die Lösung, so hässlich sie auch ist, besteht darin, den Inhalt von FOOBAR
in einem do…while
Erklärung:
#define FOOBAR() \
do { \
if (foo) \
[Bar fooBar]; \
} while(0) /*semicolon omitted*/
Da wir das Semikolon in der Makrodefinition weglassen, wird die do…while
ist eine nicht beendete Anweisung, so dass das Semikolon außerhalb der Makroverwendung an sie gebunden wird. Dann sieht unser erweiterter Code wie folgt aus:
//First, the unexpanded code again
if (bar)
FOOBAR();
else
do_something_else();
//Expanded
if (bar)
do
{
if (foo)
[Bar fooBar];
}
while(0);
else
do_something_else();
En else
bindet nun an if (bar)
wie Sie es beabsichtigt haben.