简体   繁体   English

多行预处理器宏

[英]Multi line preprocessor macros

How to make multi line preprocessor macro?如何制作多行预处理器宏? I know how to make one line:我知道如何制作一行:

#define sqr(X) (X*X)

but I need something like this:但我需要这样的东西:

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

How can I get this to work?我怎样才能让它工作?

This is only an example, the real macro may be very long.这只是一个例子,真正的宏可能很长。

You use \\ as a line continuation escape character.您使用\\作为换行符转义符。

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

EDIT: As @abelenky pointed out in the comments, the \\ character must be the last character on the line .编辑:正如@a​​belenky 在评论中指出的那样, \\字符必须是该行的最后一个字符 If it is not (even if it is just white space afterward) you will get confusing error messages on each line after it.如果不是(即使它之后只是空白),您将在其后的每一行上看到令人困惑的错误消息。

You can make a macro span multiple lines by putting a backslash ( \\ ) at the end of each line:您可以通过在每行末尾放置一个反斜杠 ( \\ ) 来使宏跨越多行:

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

PLEASE NOTE as Kerrek SB and coaddict pointed out, which should have been pointed out in the accepted answer, ALWAYS place braces around your arguments.请注意,正如 Kerrek SB 和 coaddict 指出的那样,应该在已接受的答案中指出这一点,始终在您的论点周围加上大括号。 The sqr example is the simple example taught in CompSci courses. sqr 示例是 CompSci 课程中教授的简单示例。

Here's the problem: If you define it the way you did what happens when you say "sqr(1+5)"?问题是:如果你按照你的方式定义它,当你说“sqr(1+5)”时会发生什么? You get "1+5*1+5" or 11你得到 "1+5*1+5" 或 11
If you correctly place braces around it, #define sqr(x) ((x)*(x))如果你正确地在它周围放置了大括号,# #define sqr(x) ((x)*(x))
you get ((1+5) * (1+5)) or what we wanted 36 ...beautiful.你得到 ((1+5) * (1+5)) 或者我们想要的 36 ...漂亮。

Ed S. is going to have the same problem with 'swap' Ed S. 将遇到与“交换”相同的问题

You need to escape the newline at the end of the line by escaping it with a \\ :您需要通过用\\转义来转义行尾的换行符:

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

Although this wasn't part of the original question, none of the other answers mention that comments embedded in multi-line macros require careful attention.尽管这不是原始问题的一部分,但其他答案都没有提到嵌入在多行宏中的注释需要仔细注意。

  • C++ style comments may not appear on any line having a line continuation escape character. C++ 风格的注释不能出现在任何具有换行符的行上。
  • C-style comments may not span multiple lines separated by a line continuation escape character. C 风格的注释不能跨越由换行符分隔的多行。

Examples:例子:

// 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();                  \
};

We can write multi-line macro same like function, but each statement ends with “\\” .我们可以像函数一样编写多行宏,但每个语句都以“\\”结尾。 Let us see with example.让我们举例看看。 Below is simple macro, which accepts input number from user, and prints whether entered number is even or odd下面是简单的宏,它接受用户输入的数字,并打印输入的数字是偶数还是奇数

#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;
}

This is 2021 and we should really be moving towards inline .这是 2021 年,我们真的应该朝着inline迈进。 Incorrect, unnecessary and overuse of macros bloats the code and they are hard to debug ( read really hard to debug )不正确、不必要和过度使用宏会使代码膨胀并且难以调试(阅读真的很难调试)

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

if, however macros are really the need of the hour, surrounding them with a do { } while(0);然而,如果宏确实是一个小时的需要,用do { } while(0); reason is explained in this post Why use apparently meaningless do-while and if-else statements in macros?原因在这篇文章中解释了为什么在宏中使用明显毫无意义的 do-while 和 if-else 语句?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM