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

3 iphone cocoa cocoa-touch objective-c

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

if (foo) {
[Bar fooBar];
}
Run Code Online (Sandbox Code Playgroud)

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

Pet*_*sey 8

使用\来转义您希望成为宏的一部分的每个换行符.

但是,请注意,如果您不小心,使用这样的宏可以隐藏结构.举个例子:

if (bar)
    FOOBAR();
else
    do_something_else();
Run Code Online (Sandbox Code Playgroud)

猜猜这扩展到了什么.可能不是你的想法.这是编译器看到的内容(缩进调整):

if (bar)
    if (foo)
        {
            [Bar fooBar];
        }
;
    else
        do_something_else();
Run Code Online (Sandbox Code Playgroud)

哎呀!分号是一个单独的空语句.每个if只需一个声明; 第一个if语句是第二个if,第二个if语句是复合语句({…}),因此它们都满足了它们的配额,而不是分号.

所以分号不一定是if-it的无条件.当您尝试将其应用于else无条件语句时,这会导致语法错误.

此修复程序,丑陋的,因为它是,是包装的内容物FOOBARdo…while的语句:

#define FOOBAR()       \
    do {                \
        if (foo)         \
            [Bar fooBar]; \
    } while(0) /*semicolon omitted*/
Run Code Online (Sandbox Code Playgroud)

因为我们在宏定义中省略了分号,所以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();
Run Code Online (Sandbox Code Playgroud)

else如今结合if (bar),如你意.


Mar*_*som 5

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