多行预处理器宏

时间:2012-05-02 18:25:58

标签: c++ c c-preprocessor

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

#define sqr(X) (X*X)

但我需要这样的事情:

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

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

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

7 个答案:

答案 0 :(得分:98)

使用\作为行继续转义字符。

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

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

答案 1 :(得分:15)

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

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

答案 2 :(得分:13)

请注意正如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'相同的问题

答案 3 :(得分:3)

你需要通过使用\转义它来转义该行末尾的换行符:

#define sqr(X) \
        ((X)*(X))

答案 4 :(得分:0)

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

  • C++ 风格的注释不能出现在任何带有换行符的行上。
  • C 风格的注释不能跨越由换行符分隔的多行。

示例:

// WRONG:
#define someMacro(X)          \
// This comment is a problem. \
class X : public otherClass   \
{                             \
     int foo;                 \
     void doFoo();            \
};

// WRONG:
#define someMacro(X)        \
/* This comment is also     \
 * a problem. */            \
class X : public otherClass \
{                           \
     int foo;               \
     void doFoo();          \
};

// OK:
#define someMacro(X)                \
/* This comment is fine. */         \
class X : public otherClass         \
{                                   \
     int foo; /* This is OK too! */ \
     void doFoo();                  \
};

答案 5 :(得分:0)

我们可以像函数一样编写多行宏,但每个语句都以“\”结尾。让我们举例看看。下面是简单的宏,它接受用户输入的数字,并打印输入的数字是偶数还是奇数

#include <stdio.h>
  
#define MACRO(num, str) ({\
            printf("%d", num);\
            printf(" is");\
            printf(" %s number", str);\
            printf("\n");\
           })
  
int main(void)
{
    int num;
  
    printf("Enter a number: ");
    scanf("%d", &num);
  
    if (num & 1)
        MACRO(num, "Odd");
    else
        MACRO(num, "Even");
  
    return 0;
}

答案 6 :(得分:0)

现在是 2021 年,我们真的应该朝着 inline 迈进。不正确、不必要和过度使用宏会使代码膨胀并且难以调试(阅读真的很难调试)

inline void foo(x)
{
   // do whatever with x
}

如果宏确实是一个小时的需要,在这篇文章中解释了 do { } while(0); 原因Why use apparently meaningless do-while and if-else statements in macros?