99

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.

James Wierzba
  • 16,176
  • 14
  • 79
  • 120
noisy cat
  • 2,865
  • 5
  • 33
  • 51

7 Answers7

154

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. If it is not (even if it is just white space afterward) you will get confusing error messages on each line after it.

Grhm
  • 6,726
  • 4
  • 40
  • 64
Ed S.
  • 122,712
  • 22
  • 185
  • 265
  • 52
    A word of caution: Make sure the \ is the **last** character on the line. In C, whitespace typically doesn't matter, but in this case, invisible whitespace at the end of the line can kill you. – abelenky May 02 '12 at 18:34
  • 2
    One should add that resulting text is on one line though. Because C treats all white space between tokens the same it usually doesn't matter much, but still. – Peter - Reinstate Monica Apr 17 '15 at 09:17
  • Another thing I'd suggest doing is to place `\` after all useful lines of the macro, and add a comment afterward saying something like `// Blank line required after macro`. It's sometimes easier to ensure that all lines of a macro end with `\` than to ensure all but the last line does so. – supercat Aug 15 '15 at 17:50
  • 2
    i did not know you could use the bitwise xor like that to swap variables but i wish i had thougt've it!!! – cmarangu Apr 08 '20 at 18:44
24

You can make a macro span multiple lines by putting a backslash (\) at the end of each line:

#define F(x) (x)   \
              *    \
             (x)
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
22

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. The sqr example is the simple example taught in CompSci courses.

Here's the problem: If you define it the way you did what happens when you say "sqr(1+5)"? You get "1+51+5" or 11
If you correctly place braces around it, #define sqr(x) ((x)
(x))
you get ((1+5) * (1+5)) or what we wanted 36 ...beautiful.

Ed S. is going to have the same problem with 'swap'

NOTE - Ed S. edited his answer after this post.

jiveturkey
  • 2,484
  • 1
  • 23
  • 41
  • how about `sqr(++i)`? (assume we have an `int i`) :) – Géza Török Apr 09 '15 at 11:54
  • I did it as an exercise and apparently `i` is incremented as it is substituted into the macro (in this case it is substituted twice), then it is multiplied. So `sqr(++5) == ((7) * (7))` – jiveturkey Apr 10 '15 at 17:20
  • 3
    @GézaTörök The expansion of `sqr(++i)` to `((++i)*(++i))` would invoke undefined behavior because the value of `i` is modified more than once within that statement (no sequence point between the operations). – moooeeeep Apr 16 '15 at 08:11
6

You need to escape the newline at the end of the line by escaping it with a \:

#define sqr(X) \
        ((X)*(X))
codaddict
  • 445,704
  • 82
  • 492
  • 529
6

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-style comments may not span multiple lines separated by a line continuation escape character.

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();                  \
};
sifferman
  • 2,955
  • 2
  • 27
  • 37
2

This is 2021 and we should really be moving towards 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); reason is explained in this post Why use apparently meaningless do-while and if-else statements in macros?

asio_guy
  • 3,667
  • 2
  • 19
  • 35
  • Finally, someone who mentions the `do { /* code */ } while (0)` idiom for multiline macros. I think this is knowledge that needs to be disseminated more, because I still see people writing multiline macros with a plain `{ /* code */ }` and then get sloppy with semicolons. – phetdam Mar 29 '23 at 15:07
0

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