Multi line preprocessor macros
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.
Multiline preprocessor macro with trailing comments
The problem is that the c-preprocessor just adds another line ending character when the \
is hit and continuated.
Within //
comments you can't do that. The \
character isn't accepted to continuate the comment (it's supposed to appear as a single line anyway).
The solution is,- as you found out yourself -, to use the /**/
comment style.
Can we write a macro in many lines without the backslash at the end?
Multi-line macro definitions without backslash-newline
Since comments are replaced by spaces in translation phase 3:
- The source file is decomposed into preprocessing tokens7) and sequences of
white-space characters (including comments). A source file shall not end in a
partial preprocessing token or in a partial comment. Each comment is replaced by
one space character. New-line characters are retained. Whether each nonempty
sequence of white-space characters other than new-line is retained or replaced by
one space character is implementation-defined.
and the preprocessor runs as phase 4:
- Preprocessing directives are executed, macro invocations are expanded, and
_Pragma
unary operator expressions are executed. If a character sequence that
matches the syntax of a universal character name is produced by token
concatenation (6.10.3.3), the behavior is undefined. A#include
preprocessing
directive causes the named header or source file to be processed from phase 1.
through phase 4, recursively. All preprocessing directives are then deleted.
it is possible, but absurd, to write a multi-line macro like this:
#include <stdio.h>
#define possible_but_absurd(a, b) /* comments
*/ printf("are translated"); /* in phase 3
*/ printf(" before phase %d", a); /* (the preprocessor)
*/ printf(" is run (%s)\n", b); /* but why abuse the system? */
int main(void)
{
printf("%s %s", "Macros can be continued without backslashes",
"because comments\n");
possible_but_absurd(4, "ISO/IEC 9899:2011,\nSection 5.1.1.2"
" Translation phases");
return 0;
}
which, when run, states:
Macros can be continued without backslashes because comments
are translated before phase 4 is run (ISO/IEC 9899:2011,
Section 5.1.1.2 Translation phases)
Backslash-newline in macro definitions
Translation phases 1 and 2 are also somewhat relevant:
- Physical source file multibyte characters are mapped, in an implementation-defined
manner, to the source character set (introducing new-line characters for
end-of-line indicators) if necessary. Trigraph sequences are replaced by
corresponding single-character internal representations.
The trigraph replacement is nominally relevant because ??/
is the trigraph for a backslash.
- Each instance of a backslash character (
\
) immediately followed by a new-line
character is deleted, splicing physical source lines to form logical source lines.
Only the last backslash on any physical source line shall be eligible for being part
of such a splice. A source file that is not empty shall end in a new-line character,
which shall not be immediately preceded by a backslash character before any such
splicing takes place.
This tells you that by the time phase 4 (the preprocessor) is run, macro definitions are on a single (logical) line — the trailing backslash-newline combinations have been deleted.
The standard notes that the phases are 'as if' — the behaviour of the compiler must be as if it went through the separate phases, but many implementations do not formally separate them out fully.
Avoid the GCC extension
The expanded example (quote from the GCC manual) has the invocation spread over many lines, but the definition is strictly on one line. (This much is not a GCC extension but completely standard behaviour.)
Note that if you're remotely sane, you'll ignore the possibility of putting preprocessing directives within the invocation of a macro (the #undef
and #define
in the example). It is a GCC extension and totally unportable. The standard says that the behaviour is undefined.
Annex J.2 Undefined behavior
- There are sequences of preprocessing tokens within the list of macro arguments that would otherwise act as preprocessing directives (6.10.3).
how to combine multiline macros in C with comments at the end of a line
According to a comment, It seems to be an XY-problem. A macro might not be the best approach.
If you are up to a table of constants, the normal way would be just to generate an array once and use that throughout your code:
static const float cal_table [5] = {
0.001, // 5 mV
0.002, // 10 mV
0.004, // 20 mV
0.007, // 35 mV
0.013 // 65 mV
};
If that is only used in a single file, make it static
as shown, else remove the static
and add
extern const float cal_table[5];
to the header file of the module.
Note that, if this is for a small MCU (AVR/PIC) without floating point unit, you might be better off with not using float
, but fixed-point simulated by integers (e.g. scaled to 1mV).
You can also use this as an initializer for an auto
array variable. Make that array a typedef
, generate the const
as described and memcpy
the array to the local variable as required. This is as fast as an initializer, because the compiler also has to copy that to the local array. So you use the const
array as a template (still having a single location to change, if required) .
python regex to match multi-line preprocessor macro
This is a simple test program I knocked up:
#!/usr/bin/env python
TEST1="""
#include "Foo.h"
#define bar foo\\
x
#include "Bar.h"
"""
TEST2="""
#define bar foo
#define x 1 \\
12 \\
2 \\\\ 3
Foobar
"""
TEST3="""
#define foo(x) if(x) \\
doSomething(x)
"""
TEST4="""
#define foo(x) if(x) \\
doSomething(x)
normalCode();
"""
import re
matcher = re.compile(r"^[ \t]*#define(.*\\\n)+.*$",re.MULTILINE)
def extractDefines(s):
mo = matcher.search(s)
if not mo:
print mo
return
print mo.group(0)
extractDefines(TEST1)
extractDefines(TEST2)
extractDefines(TEST3)
extractDefines(TEST4)
The re I used:
r"^[ \t]*#define(.*\\\n)+.*$"
Is very similar to the one use used, the changes:
- [ \t] To avoid newlines at the start
of the define. - I rely on + being
greedy, so I can use a simple .*$ at
the end to get the first line of the
define that doesn't end with \
Related Topics
C++ Dll Export: Decorated/Mangled Names
How to Programmatically Get the Version of a Dll or Exe File
Requesting Administrator Privileges At Run Time
Determine If a Type Is an Stl Container At Compile Time
Append an Int to a Std::String
How Does This Template Magic Determine Array Parameter Size
Using Unicode in C++ Source Code
Conversion of 2D Array to Pointer-To-Pointer
How to Pass a Reference to a Two-Dimensional Array to a Function
C++: Constructor Initializer For Arrays
Opencv Get Pixel Channel Value from Mat Image
Getting Started With Opencv 2.4 and Mingw on Windows 7
Difference Between "If Constexpr()" VS "If()"
Why Do We Not Have a Virtual Constructor in C++
View Array in Visual Studio Debugger
How to Implement Matlab'S Mldivide (A.K.A. the Backslash Operator "\")