Macro and Symbolic Constants: #define

You can use a #define preprocessor directive to define a piece of text which will be substituted for another piece of text wherever it occurs in the source file after the line containing the #define. This also affects any #ifdef and #ifndef directives that occur later in the file. There are two basic forms of #define. The first defines a simple text substitution, the second performs a more complex 'macro' substitution.

By convention all macros and symbolic constants have names that are ALL_CAPITOLS. This helps them stand out in the code and makes sure you do not confuse them with ordinary variables or function calls.

Symbolic Constants

The following two directives are examples of simple text substitution or symbolic constants.

#define MAGIC_NUMBER 12874538
#define BAR

The first line means that any occurance of the text "MAGIC_NUMBER" after the #define will be replaced by the text "12874538". The second line means that BAR will be replaced by no text at all (which can be useful if there are cases where you need to insert a special keyword and other cases where no keyword is required in the same position).

Such definitions are useful for keeping the definition of shared constants and magic formulae isolated. You might use the magic number in several places in your source code, but by using MAGIC_NUMBER instead of the number itself you can change the magic number definition in one place (in a header file most likely) if the number changes.

One of the most common uses of symbolic constants is for buffer sizes. For example:

#define BUFFER_SIZE 64

char caBuffer[BUFFER_SIZE];

void FillBuffer (char c)
{
  int i;
  for (i = 0; i < BUFFER_SIZE; ++i)
  {
    caBuffer[i] = c;
  }
}

Be careful with symbolic constants. They can lead to confusion.

Macros

The following directive is an example of a macro.

#define MAX(a,b) ((a)>(b) ? (a) : (b))

That definition means that later in the source code you can do something like this:

int x, y;

/* ... x and y get set to some values ... */

nMaxOfXY = MAX(x,y);

The variable nMaxOfXY will be set to the maximum of either x and y. After the preprocessing step what the compiler sees for the last line above is this:

nMaxOfXY = ((x)>(y) ? (x) : (y));

Notice how the parameters of the macro a and b were replaced by the expressions x and y used later in the code.

This kind of macro use can be dangerous. You should avoid it where possible (but it's not always possible, and it is still very common in C programs).