The #define directive
A preprocessor define directive directs the preprocessor to replace all subsequent occurrences of a macro with specified replacement tokens.
#define
directive can contain:
- A
const
object is subject to the scoping rules for variables, whereas a constant created using#define
is not. - Unlike a
const
object, the value of a macro does not appear in the intermediate representation used by the compiler because they are expanded inline. The inline expansion makes the macro value unavailable to the debugger. - A macro can be used in a compile-time constant expression, such as a bit
field length, whereas a
const
object cannot. - The compiler does not type-check a macro, including macro arguments.
Object-like macros
COUNT
with the constant 1000
:
#define COUNT 1000
int arry[COUNT];
int arry[1000];
in the output of the preprocessor.
COUNT
: #define MAX_COUNT COUNT + 100
The
preprocessor replaces each subsequent occurrence of MAX_COUNT
with COUNT + 100
,
which the preprocessor then replaces with 1000 + 100
.
#define a 10
doubl d = a.2
In C++11, the diagnostic for object-like macros in the C99 preprocessor is adopted to provide a common preprocessor interface for C and C++ compilers. The C++11 compiler issues a warning message if there are no white spaces between an object-like macro name and its replacement list in a macro definition. For more information, see C99 preprocessor features adopted in C++11 (C++11).
Function-like macros
More complex than object-like macros, a function-like macro definition declares the names of formal parameters within parentheses, separated by commas. An empty formal parameter list is legal: such a macro can be used to simulate a function that takes no arguments. C99 adds support for function-like macros with a variable number of arguments.
- Function-like macro definition:
- An identifier followed by a parameter list in parentheses and
the replacement tokens. The parameters are imbedded in the replacement
code. White space cannot separate the identifier (which is the name
of the macro) and the left parenthesis of the parameter list. A comma
must separate each parameter.
For portability, you should not have more than 31 parameters for a macro. The parameter list may end with an ellipsis (…) as the formal parameter. In this case, the identifier
__VA_ARGS__
may appear in the replacement list. - Function-like macro invocation:
- An identifier followed by a comma-separated list of arguments
in parentheses. The number of arguments should match the number of
parameters in the macro definition, unless the parameter list in the
definition ends with an ellipsis. In this latter case, the number
of arguments in the invocation should match or exceed
the number of parameters in the definition. The excess are called trailing
arguments. Once the preprocessor identifies a function-like macro
invocation, argument substitution takes place. A parameter in the
replacement code is replaced by the corresponding argument. If trailing
arguments are permitted by the macro definition, they are merged with
the intervening commas to replace the identifier
__VA_ARGS__
, as if they were a single argument. Any macro invocations contained in the argument itself are completely replaced before the argument replaces its corresponding parameter in the replacement code.A macro argument can be empty (consisting of zero preprocessing tokens). For example,#define SUM(a,b,c) a + b + c SUM(1,,3) /* No error message. 1 is substituted for a, 3 is substituted for c. */
__VA_ARGS__
in the replacement list. The
following example illustrates this: #define debug(...) fprintf(stderr, __VA_ARGS__)
debug("flag"); /* Becomes fprintf(stderr, "flag"); */
- In character constants
- In string literals
- Surrounded by parentheses
SUM
as
having two parameters a
and b
and
the replacement tokens (a + b)
: #define SUM(a,b) (a + b)
c = SUM(x,y);
c = d * SUM(x,y);
c = (x + y);
c = d * (x + y);
#define SQR(c) ((c) * (c))
c
in the definition
in order to correctly evaluate an expression like: y = SQR(a + b);
y = ((a + b) * (a + b));
y = (a + b * a + b);
Arguments
of the #
and ##
operators are converted before replacement
of parameters in a function-like macro.
Once defined, a preprocessor
identifier remains defined independent of the
scoping rules of the language. The scope of a macro definition begins
at the definition and does not end until a corresponding #undef
directive
is encountered. If there is no corresponding #undef
directive,
the scope of the macro definition lasts until the end of the translation
unit.
#define x(a,b) x(a+1,b+1) + 4
x(20,10)
x(20+1,10+1) + 4
rather
than trying to expand the macro x
over and over within
itself. After the macro x
is expanded, it is a call
to function x()
.
debug
from subsequent lines
in the current file: #define debug
You
can change the definition of a defined identifier or macro with a
second preprocessor #define
directive only if the
second preprocessor #define
directive is preceded
by a preprocessor #undef
directive. The #undef
directive
nullifies the first definition so that the same identifier can be
used in a redefinition.
Within the text of the program, the preprocessor does not scan comments, character constants, or string constants for macro definitions, undefining a macro, or macro invocations.
The following example program contains two macro definitions and a macro invocation that refers to both of the defined macros:
CCNRAA8
/**This example illustrates #define directives.**/
void printf(const char*, ...);
#define SQR(s) ((s) * (s))
#define PRNT(a,b) \
printf("value 1 = %d\n", a); \
printf("value 2 = %d\n", b)
int main(void)
{
int x = 2;
int y = 3;
PRNT(SQR(x),y);
return(0);
}
After being preprocessed, this program is replaced by code equivalent to the following:
CCNRAA9
void printf(const char*, ...);
int main(void)
{
int x = 2;
int y = 3;
printf("value 1 = %d\n", ( (x) * (x) ) );
printf("value 2 = %d\n", y);
return(0);
}
value 1 = 4
value 2 = 3
Variadic macro extensions
refer to two extensions to C99 and C++03 related
to macros with variable number of arguments. One extension is a mechanism
for renaming the variable argument identifier from __VA_ARGS__
to
a user-defined identifier. The other extension provides a way to remove
the dangling comma in a variadic macro when no variable arguments
are specified. Both extensions have been implemented to facilitate
porting programs developed with GNU C and C++.
__VA_ARGS__
.
The first definition of the macro debug
exemplifies
the usual usage of __VA_ARGS__
. The second definition
shows the use of the identifier args
in place of __VA_ARGS__
.
#define debug1(format, ...) printf(format, ## __VA_ARGS__)
#define debug2(format, args ...) printf(format, ## args)
Invocation | Result of macro expansion |
---|---|
debug1("Hello %s/n", "World"); |
printf("Hello %s/n", "World"); |
debug2("Hello %s/n", "World"); |
printf("Hello %s/n", "World"); |
##
precedes the variable argument
identifier in the function macro definition. In C++11, the variadic macros feature and changes concerning empty macro arguments are adopted from the C99 preprocessor to provide a common preprocessor interface for C and C++ compilers. Variadic macros and empty macro arguments are supported in C++11. For more information, see C99 preprocessor features adopted in C++11 (C++11).