The #define directive

A preprocessor define directive directs the preprocessor to replace all subsequent occurrences of a macro with specified replacement tokens.

Read syntax diagramSkip visual syntax diagram#define directive syntax
                          |    .-,--------------.    |
                          |    V                |    |
   V                |

The #define directive can contain:

The following are some differences between #define and the const type qualifier:

Related information

Object-like macros

An object-like macro definition replaces a single identifier with the specified replacement tokens. The following object-like definition causes the preprocessor to replace all subsequent instances of the identifier COUNT with the constant 1000 :

#define COUNT 1000

If the statement

int arry[COUNT];

appears after this definition and in the same file as the definition, the preprocessor would change the statement to

int arry[1000];

in the output of the preprocessor.

Other definitions can make reference to the identifier 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.

If a number that is partially built by a macro expansion is produced, the preprocessor does not consider the result to be a single value. For example, the following will not result in the value 10.2 but in a syntax error.

#define a 10

Identifiers that are partially built from a macro expansion may not be produced. Therefore, the following example contains two identifiers and results in a syntax error:

#define d efg

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. XL C++ supports function-like macros with a variable number of arguments, as a language extension for compatibility with C.

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 (...). 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 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. */

If the identifier list does not end with an ellipsis, the number of arguments in a macro invocation must be the same as the number of parameters in the corresponding macro definition. During parameter substitution, any arguments remaining after all specified arguments have been substituted (including any separating commas) are combined into one argument called the variable argument. The variable argument will replace any occurrence of the identifier __VA_ARGS__ in the replacement list. The following example illustrates this:

#define debug(...)   fprintf(stderr, __VA_ARGS__)

debug("flag");     /*   Becomes fprintf(stderr, "flag");   */

Commas in the macro invocation argument list do not act as argument separators when they are:

The following line defines the macro SUM as having two parameters a and b and the replacement tokens (a + b):

#define SUM(a,b) (a + b)

This definition would cause the preprocessor to change the following statements (if the statements appear after the previous definition):

c = SUM(x,y);
c = d * SUM(x,y);

In the output of the preprocessor, these statements would appear as:

c = (x + y);
c = d * (x + y);

Use parentheses to ensure correct evaluation of replacement text. For example, the definition:

#define SQR(c)  ((c) * (c))

requires parentheses around each parameter c in the definition in order to correctly evaluate an expression like:

y = SQR(a + b);

The preprocessor expands this statement to:

y = ((a + b) * (a + b));

Without parentheses in the definition, the correct order of evaluation is not preserved, and the preprocessor output is:

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 and in scope 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.

A recursive macro is not fully expanded. For example, the definition

   #define x(a,b) x(a+1,b+1) + 4




   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().

A definition is not required to specify replacement tokens. The following definition removes all instances of the token 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 character constants or string constants for macro invocations.

The following example program contains two macro definitions and a macro invocation that refers to both of the defined macros:

 ** This example illustrates #define directives.

#include <stdio.h>

#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;



After being interpreted by the preprocessor, this program is replaced by code equivalent to the following:

#include <stdio.h>

int main(void)
  int x = 2;
  int y = 3;

     printf("value 1 = %d\n", ( (x) * (x) ) );
     printf("value 2 = %d\n", y);


This program produces the following output:

value 1 = 4
value 2 = 3

Related information

IBM extension
Variadic macro extensions

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++.

The following examples demonstrate the use of an identifier in place of __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");

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.

End of IBM extension