如何使用多行代码创建宏?

时间:2009-09-03 15:24:14

标签: iphone objective-c cocoa cocoa-touch

我想制作一个会注入一些代码的宏,比如:

if (foo) {
[Bar fooBar];
}

然后,在我需要的地方,我把FOOBAR放在代码中。不确定,但在编译时,编译器将其替换为实际代码,如上例所示。也许有一些不同于我可以使用的宏?

2 个答案:

答案 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)

您可以通过在除最后一行之外的每行的末尾添加\来在多行上定义宏。不幸的是,当您实际使用它时,宏将扩展为单行。