多行预处理器宏

noi*_*cat 69 c c++ c-preprocessor

如何制作多行预处理器宏?我知道怎么做一行:

#define sqr(X) (X*X)
Run Code Online (Sandbox Code Playgroud)

但我需要这样的东西:

#define someMacro(X)
    class X : public otherClass
    {
         int foo;
         void doFoo();
    };
Run Code Online (Sandbox Code Playgroud)

我怎样才能让它发挥作用?

这只是一个例子,真正的宏可能很长.

Ed *_* S. 108

\用作行继续转义字符.

#define swap(a, b) {               \
                       (a) ^= (b); \
                       (b) ^= (a); \
                       (a) ^= (b); \
                   }
Run Code Online (Sandbox Code Playgroud)

编辑:正如@a​​belenky在评论中指出的那样,\角色必须是该行的最后一个角色.如果不是(即使之后只是空白区域),您将在其后的每一行上收到混乱的错误消息.

  • 提醒一句:确保\是该行上的**最后**字符.在C中,空格通常无关紧要,但在这种情况下,行尾的不可见空格可能会杀死你. (39认同)
  • 应该添加结果文本在一行上.因为C处理令牌之间的所有空白区域通常并不重要,但仍然如此. (2认同)
  • 我不知道你可以使用像这样的按位异或来交换变量,但我希望我已经想到了! (2认同)

Ker*_* SB 17

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

#define F(x) (x)   \
              *    \
             (x)
Run Code Online (Sandbox Code Playgroud)

  • +1:因为没有错过`x`周围的括号! - ) (7认同)

jiv*_*key 15

请注意,正如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.将与'swap'有同样的问题

  • @GézaTörök `sqr(++i)` 到 `((++i)*(++i))` 的扩展会调用未定义的行为,因为 `i` 的值在该语句中被修改了多次(没有操作之间的序列点)。 (2认同)

sif*_*man 7

尽管这不是原始问题的一部分,但其他答案都没有提到嵌入多行宏中的注释需要仔细注意。

  • C++ 风格的注释不能出现在任何具有行继续转义字符的行上。
  • C 样式注释不能跨越由行继续转义字符分隔的多行。

例子:

// WRONG:
#define someMacro(X)          \
// This comment is a problem. \
class X : public otherClass   \
{                             \
     int foo;                 \
     void doFoo();            \
};
Run Code Online (Sandbox Code Playgroud)
// WRONG:
#define someMacro(X)        \
/* This comment is also     \
 * a problem. */            \
class X : public otherClass \
{                           \
     int foo;               \
     void doFoo();          \
};
Run Code Online (Sandbox Code Playgroud)
// OK:
#define someMacro(X)                \
/* This comment is fine. */         \
class X : public otherClass         \
{                                   \
     int foo; /* This is OK too! */ \
     void doFoo();                  \
};
Run Code Online (Sandbox Code Playgroud)


cod*_*ict 6

您需要通过使用 转义来转义行尾的换行符\

#define sqr(X) \
        ((X)*(X))
Run Code Online (Sandbox Code Playgroud)