The #define directive
A preprocessor define directive directs the preprocessor to replace all subsequent occurrences of a macro with specified replacement tokens.
- 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
#define COUNT 1000
int arry[COUNT];
int arry[1000];
in the output of the preprocessor.
#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. */
#define debug(...) fprintf(stderr, __VA_ARGS__)
debug("flag"); /* Becomes fprintf(stderr, "flag"); */
- In character constants
- In string literals
- Surrounded by parentheses
#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))
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().
#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
![IBM extension](ngibm_begin.gif)
Variadic macro extensions refer to two extensions to C99 and Standard C++ 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++.
#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"); |
The preprocessor removes the trailing comma if the variable arguments to a function macro are omitted or empty and the comma followed by ## precedes the variable argument identifier in the function macro definition.
![IBM extension](ngibm_end.gif)
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).