我想制作一个会注入一些代码的宏,比如:
if (foo) {
[Bar fooBar];
}
然后,在我需要的地方,我把FOOBAR放在代码中。不确定,但在编译时,编译器将其替换为实际代码,如上例所示。也许有一些不同于我可以使用的宏?
答案 0 :(得分:8)
使用\来转义您希望成为宏的一部分的每个换行符。
但是,请注意,如果您不小心,使用这样的宏可以隐藏结构。举个例子:
if (bar)
FOOBAR();
else
do_something_else();
猜猜这扩展到了什么。可能不是你的想法。这是编译器看到的内容(缩进调整):
if (bar)
if (foo)
{
[Bar fooBar];
}
;
else
do_something_else();
糟糕!分号是一个单独的空语句。每个if
只需要一个语句;第一个if
的语句是第二个if
,第二个if
的语句是复合语句({…}
),因此它们都满足了它们的配额,把分号留下来。
所以分号没有绑定if
- 它是无条件的。当您尝试将else
应用于无条件语句时,这会导致语法错误。
修复程序,实际上是丑陋的,是将FOOBAR
的内容包装在do…while
语句中:
#define FOOBAR() \
do { \
if (foo) \
[Bar fooBar]; \
} while(0) /*semicolon omitted*/
因为我们在宏定义中省略了分号,do…while
是一个未终止的语句,因此宏用法之外的分号将绑定到它。然后我们的扩展代码如下所示:
//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();
else
现在按照您的意图绑定到if (bar)
。
答案 1 :(得分:5)
您可以通过在除最后一行之外的每行的末尾添加\来在多行上定义宏。不幸的是,当您实际使用它时,宏将扩展为单行。