A macro is defined with the directive #define
. It
is followed by the macro name, and then the
definition:
- control-line
# define identifier replacement-listopt new-line
- replacement-list
pp-tokensopt
For example:
#define UNIVERSAL_CONSTANT 42
This macro is called UNIVERSAL_CONSTANT
, and it expands to
42
. Note that the expansion is not
a number or an int
, but
the text 42
(there is almost no
notion of type in
this phase of translation). When the
macro name is encountered, it is replaced by the
expansion, so this line:
int meaning = UNIVERSAL_CONSTANT;
…would become:
int meaning = 42;
Only during a later phase will the expansion in this
case be then treated as a constant of type int
.
As text, the expansion can take almost any form necessary. The following macro expands to something that could be interpreted later as a string literal:
#define STRING "This is a string."
The definition must fit onto one line. However, an
earlier phase of translation folds together one line with
the following if it ends in a backslash \
U+005C, so this can
be used to build a multiline macro definition:
#define VERY_LONG_STRING "This is a string, " \
"and no-one but me " \
"can change it."
Macros can be defined to take arguments, and so become function-like:
- control-line
# define ident-lparen identifier-listopt ) replacement-list new-line
- replacement-list
pp-tokensopt
- ident-lparen
-
identifier (
without intervening white space
For example:
#define SUM(x, y) x + y
There must be no space between the macro name and the opening bracket of its parameter list, or the parameter list will be misinterpreted as part of replacement-list.
Macro calls match the grammar of macro-call:
- macro-call
identifier ( macro-arg-listopt )
- macro-arg-list
macro-arg
macro-arg-list , macro-argopt
- macro-arg
macro-token
macro-arg macro-token
- macro-token
( macro-arg )
-
preprocessing-token
except for(
and)
new-line
sp
Comma ought to be excluded too, but only at the top level. macro-arg in brackets should also be optional.
For example:
#define SUM(x, y) x + y printf("sum is %d\n", SUM(10, 20));
This expands to:
printf("sum is %d\n", 10 + 20);
…which appears to produce the correct result. However, special care must be taken when using function-like macros, as they only perform a textual substitution. Consider:
#define SUM(x, y) x + y printf("sum is %d\n", 3 * SUM(10, 20) * 4);
We might expect this to print out:
sum is 360
…but we actually get:
sum is 110
…because the expansion is actually:
printf("sum is %d\n", 3 * 10 + 20 * 4);
The macro has taken no account of operator
precedence, causing the evaluation of (3 * 10) + (20 * 4)
instead of 3 * (10 + 20) * 4
, and we have to fix it by
wrapping the expression in parentheses:
#define SUM(x, y) (x + y) printf("sum is %d\n", 3 * SUM(10, 20) * 4);
Now the text expands to:
printf("sum is %d\n", 3 * (10 + 20) * 4);
…which gives the expected result. That deals with
operators with higher precedence than +
outside of the expansion, yet the macro
definition is still not safe. Consider:
#define SUM(x, y) (x + y) printf("sum is %d\n", SUM(10 & 13, 20));
We expect this to print:
sum is 28
…because 10 & 13 == 8
but we
actually get:
sum is 33
…because the expansion is actually:
printf("sum is %d\n", (10 & 13 + 20));
This time, the problem is with operators with lower
precedence than +
inside the
arguments. We must protect against that with more
brackets:
#define SUM(x, y) ((x) + (y)) printf("sum is %d\n", SUM(10 & 13, 20));
…becomes:
printf("sum is %d\n", ((10 & 13) + (20)));
Even now, there are still potential problems. Consider:
#define DOUBLE(x) ((x) + (x)) printf("double is %d\n", DOUBLE(a++));
…which becomes:
printf("double is %d\n", ((a++) + (a++)));
We now have the variable a
being incremented twice. Even in a fully specified
environment, this would be an error, since our intention
was probably only to increment once, but this expression
actually has undefined behaviour, because an
expression is not allowed to modify a single object twice
without an intervening sequence point. In short, don't
use expressions with side effects as macro arguments,
unless the macro is specified not to use the expression
more than once. See getc
and fgetc
for an example of this.
See inline
for an
alternative to function-like macros.
Macro definitions can do some clever things with their
arguments. The concatenation operator ##
joins two expansions together into a single token. For
example, this:
#define foo(a, b) a ## b foo(pri, ntf)("Yes!\n");
…expands to this:
printf ("Yes!\n");
Without ##
,
the best we could get is:
pri ntf ("Yes!\n");
And this form also would not work:
#define foo(a, b) ab
…as ab
is not recognized as two
adjacent tokens, and so produces:
ab ("Yes!\n");
The stringifying operator #
makes a string literal out of its operand:
#define debug(X) printf("%s = %g\n", # X, (double) (X)) debug(x + y);
That produces:
printf("%s = %g\n", "x + y", (double) (x + y))
Variadic macros
C99 allows a macro to
accept any number of arguments beyond its named
parameters if its last parameter is ...
. These additional arguments, being
unnamed, cannot be accessed individually, but only as
a unit using the special token __VA_
.
- control-line
-
# define ident-lparen ... ) replacement-list new-line
since C99 -
# define ident-lparen identifier-list , ... ) replacement-list new-line
since C99
You might want to define a macro that expands to a
call to fprintf
:
#define DEBUG(M, ...) \ fprintf(stderr, M, __VA_ARGS__ )
That appears to do the job:
DEBUG("x=%d y=%g\n", x, y); DEBUG("x=%d\n", x);
…but it stops working if there are no additional arguments, as this:
DEBUG("here\n");
…expands to this:
fprintf(stderr, "here\n", )
…so the compiler will complain about a missing argument.
The simplest solution in this case is to make
M
part of the variable-length
list:
#define DEBUG(...) \ fprintf(stderr, __VA_ARGS__ )
This is fine, so long as you don't need to insert
anything after M
. The
technique cannot be applied directly to cases like
these:
#define DEBUG(M, ...) \ fprintf(stderr, M "\n", __VA_ARGS__ ) #define DEBUG(M, ...) \ fprintf(stderr, "%s:%d: " M "\n", __FILE__, __LINE__, __VA_ARGS__ )
You might have to split your call to fprintf
into several, which
you might be able to do in a single macro:
#define DEBUG(M, ...) \ (fprintf(stderr, "%s:%d: ", __FILE__, __LINE__), \ fprintf(stderr, __VA_ARGS__ ), \ fprintf(stderr, "\n"))
…or which you might have to do in an extra function:
#define DEBUG(...) \ debug(__FILE__, __LINE__, __VA_ARGS__ ) void debug(const char *fn, int ln const char *msg, ...) { fprintf(stderr, "%s:%d: ", fn, ln); va_list ap; va_start (ap, msg); vfprintf(stderr, msg, ap); va_end (ap); fprintf(stderr, "\n"); }
These techniques only work if the format argument is immediately before its corresponding list. If you can't arrange for that to happen, you have to resort to more esoteric techniques:
// Based on a StackOverflow answer by James McNellis #define DEPAREN(...) __VA_ARGS__ #define PP_HAS_ARGS_IMPL2(_1, _2, _3, _4, _5, _6, _7, N, ...) N #define PP_HAS_ARGS_SOURCE() \ MULTI, MULTI, MULTI, MULTI, MULTI, MULTI, ONE, ERROR #define PP_HAS_ARGS_IMPL(...) \ PP_HAS_ARGS_IMPL2(__VA_ARGS__) #define PP_HAS_ARGS(...) \ PP_HAS_ARGS_IMPL(__VA_ARGS__, PP_HAS_ARGS_SOURCE()) #define DISAMB2(PFX, has_args, ...) \ PFX ## _ ## has_args ( __VA_ARGS__) #define DISAMB(PFX, FARGS, has_args, ...) \ DISAMB2(PFX, has_args, DEPAREN FARGS __VA_ARGS__)
Now you can define:
void dump(const void *base, size_t len); #define DUMP_ONE(T, S, L) \ (fprintf(stderr, "** %s:%d ** " T ":\n", \ __FILE__, __LINE__), dump((S), (L))) #define DUMP_MULTI(T, S, L, ...) \ (fprintf(stderr, "** %s:%d ** " T ":\n", \ __FILE__, __LINE__, __VA_ARGS__), dump((S), (L))) #define DUMP(T, S, ...) \ DISAMB(DUMP, (T, S, ), PP_HAS_ARGS(__VA_ARGS__), __VA_ARGS__)
…and write:
DUMP("packet", pkt, pktlen); DUMP("packet #%d", pkt, pktlen, pktnum);
If a macro needs to detect how many arguments it has received, it can use the following definitions to determine that:
/* * The PP_NARG macro evaluates to the number of arguments * that have been passed to it. * * Laurent Deniau, "__VA_NARG__," 17 January 2006, * <comp.std.c> (29 November 2007). */ #define PP_NARG(...) PP_NARG_(__VA_ARGS__,PP_RSEQ_N()) #define PP_NARG_(...) PP_ARG_N(__VA_ARGS__) #define PP_ARG_N( \ _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \ _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \ _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \ _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \ _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \ _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \ _61,_62,_63,N,...) N #define PP_RSEQ_N() \ 63,62,61,60, \ 59,58,57,56,55,54,53,52,51,50, \ 49,48,47,46,45,44,43,42,41,40, \ 39,38,37,36,35,34,33,32,31,30, \ 29,28,27,26,25,24,23,22,21,20, \ 19,18,17,16,15,14,13,12,11,10, \ 9,8,7,6,5,4,3,2,1,0