Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 567
noisy cat Avatar asked May 02 '12 18:05

noisy cat


People also ask

What is multi line macro?

A multi-line preprocessor directive, as provided in the MLM package, begins with the #begin directive and ends at the first line that starts with a #end directive that is not inside a comment or string. Both the #begin and #end directives may contain additional comments between tokens.

How do I write multiple lines in a macro?

We can write multiline macros like functions, but for macros, each line must be terminated with backslash '\' character. If we use curly braces '{}' and the macros is ended with '}', then it may generate some error. So we can enclose the entire thing into parenthesis.

What is __ LINE __ in C?

__LINE__ is a preprocessor macro that expands to current line number in the source file, as an integer. __LINE__ is useful when generating log statements, error messages intended for programmers, when throwing exceptions, or when writing debugging code.

Are macros removed after preprocessing?

Explanation: True, After preprocessing all the macro in the program are removed.


6 Answers

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.

like image 155
Ed S. Avatar answered Oct 05 '22 13:10

Ed S.


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

#define F(x) (x)   \
              *    \
             (x)
like image 27
Kerrek SB Avatar answered Oct 05 '22 14:10

Kerrek SB


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.

like image 28
jiveturkey Avatar answered Oct 05 '22 14:10

jiveturkey


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

#define sqr(X) \
        ((X)*(X))
like image 31
codaddict Avatar answered Oct 05 '22 15:10

codaddict


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();                  \
};
like image 26
sifferman Avatar answered Oct 05 '22 14:10

sifferman


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?

like image 20
asio_guy Avatar answered Oct 05 '22 15:10

asio_guy