多行预处理器宏


79

如何使多行预处理器宏?我知道如何写一行:

#define sqr(X) (X*X)

但我需要这样的东西:

#define someMacro(X)
    class X : public otherClass
    {
         int foo;
         void doFoo();
    };

我怎样才能使它工作?

这只是一个例子,实际的宏可能很长。


您可以通过搜索SO轻松获得答案。如stackoverflow.com/questions/4007865/...
永远的学习者

不同的方法在这里:parashift.com/c++
faq

Answers:


122

您可以将其\用作换行符。

#define swap(a, b) {               \
                       (a) ^= (b); \
                       (b) ^= (a); \
                       (a) ^= (b); \
                   }

编辑:正如@a​​belenky在评论中指出的那样,该\字符必须是该行上的最后一个字符。如果不是(即使之后只是空白),您将在其后的每一行上看到令人困惑的错误消息。


44
请注意:确保\是该行的最后一个字符。在C语言中,空格通常无关紧要,但是在这种情况下,行尾的不可见空格会杀死您。
abelenky 2012年

2
应该补充一点,结果文本在一行上。因为C对待标记之间的所有空白都相同,所以通常没什么关系,但是仍然如此。
彼得-恢复莫妮卡2015年

我建议做的另一件事是` after all useful lines of the macro, and add a comment afterward saying something like 在宏. It's sometimes easier to ensure that all lines of a macro end with `之后放置//空行,而不是确保除最后一行以外的所有行。
超级猫

我不知道您可以使用像这样的按位异或来交换变量,但我希望我拥有它!
cmarangu

18

您可以通过\在每行的末尾添加反斜杠()来使宏跨越多行:

#define F(x) (x)   \
              *    \
             (x)

18

请注意,正如Kerrek SB和coaddict指出的(应该在公认的答案中指出的那样),请 始终在您的论点周围加括号。sqr示例是CompSci课程中讲授的简单示例。

问题出在这里:如果您以定义方式进行操作,当您说“ sqr(1 + 5)”时会发生什么?您将获得“ 1 + 5 * 1 + 5”或11
如果在其周围正确放置括号,则将#define sqr(x) ((x)*(x))
得到((1 + 5)*(1 + 5))或我们想要的36 ...美丽。

Ed S.的“交换”将有相同的问题


怎么样sqr(++i)?(假设我们有一个int i):)
盖佐Török

我将其作为练习进行,显然i随着被替换为宏而增加(在这种情况下,它被替换了两次),然后被相乘。所以sqr(++5) == ((7) * (7))
jiveturkey

2
@GézaTörök对sqr(++i)to的扩展((++i)*(++i))将调用未定义的行为,因为i在该语句中多次修改了的值(操作之间没有顺序点)。
moooeeeep 2015年

5

您需要通过在换行符的末尾转义,以转义换行符\

#define sqr(X) \
        ((X)*(X))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.