51

How do I write a cpp macro which expands to include newlines?

jww
  • 97,681
  • 90
  • 411
  • 885
user18458
  • 511
  • 1
  • 4
  • 3
  • 2
    can you explain why you want to do this? – Lou Franco Sep 19 '08 at 03:22
  • 4
    @LouFranco probably to make it more readable? – Erel Segal-Halevi Jan 19 '14 at 17:28
  • 1
    Looking at the answers below it seems pretty clear that you can't.  Taking this into regard, the issue may be “Ur doin' it rong”.  A better solution for you (and a common one when using C macros) might be to have the macro simply do the minimal work only it can, then hand off most of the work to a helper function.  _The power of macros + functional nicely-formatted C code in non-optimized builds = win win._ – Slipp D. Thompson Jul 14 '14 at 19:44
  • 2
    This is a possible duplicate of [How to make G++ preprocessor output a newline in a macro?](http://stackoverflow.com/questions/2271078/how-to-make-g-preprocessor-output-a-newline-in-a-macro) Although the other question is more specific, it has good answers that cover all that's asked here. – Kuba hasn't forgotten Monica Aug 12 '14 at 14:49
  • It's not uncommon for languages which have meaningful whitespace (like haskell with GHC) to use the C pre-processor for constants and macro expansion. It's also used by gcc when processing assembly files (when the extension is `.S`). So that's three use cases fwiw – jberryman Dec 26 '16 at 20:14
  • 1
    This would be very useful for macros that should produce #pragmas in the expanded body. ( case at hand OpenMP ) – NoahR Apr 04 '17 at 20:09
  • I'm piping the result of `cpp` into `clang-format`. Now I get a readable result. – Jean-Bernard Jansen Apr 28 '17 at 16:54
  • Maybe relevant: [Pre-Processing using m4](https://stackoverflow.com/q/28978906/608639) and [Replacements for the C preprocessor](https://stackoverflow.com/q/396644/608639). (I really need something to add some newlines so I can untangle the macros). – jww Jul 02 '18 at 12:58

8 Answers8

20

I am working on a large project that involves a lot of preprocessor macro functions to synthesize any code that cannot be replaced by templates. Believe me, I am familiar with all sorts of template tricks, but as long as there is no standardized, type safe metaprogramming language that can directly create code, we will have to stick with good old preprocessor and its cumbersome macros to solve some problems that would require to write ten times more code without. Some of the macros span many lines and they are very hard to read in preprocessed code. Therefore, I thought of a solution to that problem and what I came up with is the following:

Let's say we have a C/C++ macro that spans multiple lines, e.g. in a file named MyMacro.hpp

// Content of MyMacro.hpp

#include "MultilineMacroDebugging.hpp"

#define PRINT_VARIABLE(S) \
__NL__  std::cout << #S << ": " << S << std::endl; \
__NL__  /* more lines if necessary */ \
__NL__  /* even more lines */

In every file where I defined such a macro, I include another file MultilineMacroDebugging.hpp that contains the following:

// Content of MultilineMacroDebugging.hpp

#ifndef HAVE_MULTILINE_DEBUGGING
#define __NL__
#endif

This defines an empty macro __NL__, which makes the __NL__ definitions disappear during preprocessing. The macro can then be used somewhere, e.g. in a file named MyImplementation.cpp.

// Content of MyImplementation.cpp

// Uncomment the following line to enable macro debugging
//#define HAVE_MULTILINE_DEBUGGING

#include "MyMacro.hpp"

int a = 10;
PRINT_VARIABLE(a)

If I need to debug the PRINT_VARIABLE macro, I just uncomment the line that defines the macro HAVE_MULTILINE_DEBUGGING in MyImplementation.cpp. The resulting code does of course not compile, as the __NL__ macro results undefined, which causes it to remain in the compiled code, but it can, however, be preprocessed.

The crucial step is now to replace the __NL__ string in the preprocessor output by newlines using your favorite text editor and, voila, you end up with a readable representation of the result of the replaced macro after preprocessing which resembles exactly what the compiler would see, except for the artificially introduced newlines.

  • google always brings me here. So for me, and everyone else, here is an online tool I found that helps restructuring the macro output: https://codebeautify.org/c-formatter-beautifier – Henrik Nov 15 '19 at 19:11
7

It is not possible. It would only be relevant if you were looking at listing files or pre-processor output.

A common technique in writing macros so that they are easier to read is to use the \ character to continue the macro onto a following line.

I (believe I) have seen compilers that include new lines in the expanded macros in listing output - for your benefit. This is only of use to us poor humans reading the expanded macros to try to understand what we really asked the compiler to do. it makes no difference to the compiler.

The C & C++ languages treat all whitespace outside of strings in the same way. Just as a separator.

itj
  • 1,165
  • 1
  • 11
  • 16
  • 27
    "It would only be relevant if you were looking at listing files or pre-processor output." That was, um, like the whole point of the question :) – Kuba hasn't forgotten Monica Aug 12 '14 at 14:46
  • 1
    It is (somewhat) possible. See [Potatoswatter's answer to *How to make G++ preprocessor output a newline in a macro?*](http://stackoverflow.com/a/2567304). For debugging, [filtering](http://stackoverflow.com/questions/2271078/how-to-make-g-preprocessor-output-a-newline-in-a-macro/24555364#24555364) [solutions](http://stackoverflow.com/questions/2271078/how-to-make-g-preprocessor-output-a-newline-in-a-macro/16096722#16096722) [can be used](http://stackoverflow.com/questions/2271078/how-to-make-g-preprocessor-output-a-newline-in-a-macro/2271579#2271579). – Peter Mortensen Feb 04 '16 at 20:02
  • FYI: I'm trying to generate a few lines of assembly in a .S file from a macro.... Alas, the assembler does NOT allow multiple statements on a line. – rew Oct 22 '20 at 15:48
  • its necessary for pragmas, which are very much whitespace sensitive – Khlorghaal Aug 09 '23 at 23:39
6

C & C++ compilers ignore unquoted whitespace (except for the > > template issue), so getting a macro to emit newlines doesn't really make sense. You can make a macro span several lines by ending each line of the macro with a backslash, but this doesn't output newlines.

Mike Thompson
  • 6,708
  • 3
  • 32
  • 39
  • 37
    It actually makes sense if you like to check the preprocessed code. Then the newlines would help to assess it's correctness for debugging purposes. – monkeydom Oct 04 '13 at 23:46
  • 9
    Why does this answer get upvotes? It doesn't answer the question. – David Baird May 03 '14 at 12:50
  • 4
    @DavidBaird Ditto. The answer doesn't really address the question. – bddicken May 30 '14 at 19:11
  • @bddicken- My situation is what monkeydom said, which actually does make sense! – David Baird Jun 04 '14 at 03:27
  • 1
    @DavidBaird @​​​bddicken: I think it's pretty easily implied from the answer that “you can't”, even if the author didn't say it directly.  And looking at the other answers, it seems that is the truth— there is no way to do this, sorry nope.  Given that, this answer is one of the shortest and most-concise in giving validation to the design of the system, the next best thing to “you can't”. – Slipp D. Thompson Jul 14 '14 at 19:40
5

The C compiler is aware of white space, but it doesn't distinguish between spaces, tabs or new lines.

If you mean how do I have a new line inside a string in a macro, then:

#define SOME_STRING "Some string\n with a new line."

will work.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
David L Morris
  • 1,461
  • 1
  • 12
  • 19
0

I have the same problem. I abuse the preprocessor on non C files, therefore the fact that the C compiler ignores line breaks is irrelevant for me. I am using \\ at the end of lines in the macro definition (which is pretty neat syntax, resembling LaTeX) and pass the result through

sed s/'\\ '/'\n'/g

This does the trick. The preprocessor strips one \ away from the \\ and joins the lines, and the sed splits them again by replacing the remaining \ by a real newline.

-4

Not quite sure what you're asking here. Do you want a macro on multiple lines?

#define NEWLINE_MACRO(x) line1 \
line2 \
line3

Additionally, if you would like to include a literal in your macro:

#define NEWLINE_MACRO(x) ##x

what you you put in x will be put in place of ##x, so:

NEWLINE_MACRO( line1 ) // is replaced with line1

This can be helpful for making custom global functions then just need part of the function name changed.

Also:

#define NEWLINE_MACRO(x) #x // stringify x

Will put quotes around x

PiNoYBoY82
  • 1,618
  • 2
  • 14
  • 17
-4

Use the \ at the end of the line. I've seen a lot of C macos where they use a do...while(0)

#define foo() do \
{
  //code goes here \
  \
  \
}while(0);

Also, remember to use parenthases in many instances.

Example:

#define foo(x) a+b
//should be
#define foo(x) (a+b)
Charles Graham
  • 24,293
  • 14
  • 43
  • 56
  • 1
    The macro definition should not include the trailing semicolon. This makes the macro call look and act like more like a function call. – Trent Sep 19 '08 at 05:03
-5

Use \, like so:

#define my_multiline_macro(a, b, c) \
if (a) { \
    b += c; \
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Branan
  • 1,819
  • 15
  • 21