11. Macros and the C Preprocessor

Table of Contents

The C Preprocessor is a part of the C compilation process that recognizes special statements, analyses them (before compilation) and acts on them as required. The preprocessor can be used to make programs more efficient, more readable, and more portable to multiple systems.

The #define statement

You can use #define statements to assign symbolic names to program constants. For example:

#define YES 1
#define PI 3.14
#define MYNAME "paul"

These are all valid uses of #define. These statements are not like variable assignment … no memory is allocated. Remember, the preprocessor acts before compilation. What is actually happening here, is quite simply, the preprocessor is going through the C code that follows, and simply substituting each instance of the symbolic name (e.g. PI) with the value that it's associated with in the #define statement (e.g. 3.14). It's like a search-and-replace, basically.

The #define statments can appear anywhere in the program, although a common convention is to put them at the top of source code files.


You can use #define statements in more advanced ways, which are sometimes called macros (a macro is typically used to define something that takes one or more arguments).

For example, you could define a macro to perform the square of a number like this:

#define SQUARE(n) n*n

Then you could use it in your code like this:

int x = 3;
int y = SQUARE(x);

Another common example of macros is to define a macro to return the maximum value of two arguments:

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

Another one is to determine if a character is lower-case:

#define IS_LOWER_CASE(x) ( ((x) >= 'a') && ((x) <= 'z') )

Variadic Macros

A Variadic macro is one with a variable number of arguments (one can also write variadic functions in C). Here is an example:

#define debugPrintf(...) printf("DEBUG: " __VA_ARGS__);

Now we could use this in the following way, either with one argument:

debugPrintf("Hello World!\n");
DEBUG: Hello World!

or with multiple arguments:

int x=12;
int y=13;
debugPrintf("x=%d, y=%d\n", x, y);
DEBUG: x=12, y=13

There are countless other examples of cool things you can do with macros. Here is a link to some examples: Macros.

The #include statement

We will be looking at this later, even though it is part of the preprocessor, when we talk about working with multiple files, and linking to libraries, etc.

Conditional compilation

One can use #ifdef, #endif, #else and #ifndef statments to achieve conditional compilation, for example to create one program that can be compiled and run on different computer systems. Similarly, one can use #if, #elif preprocessor statements to define macros differently depending on the value of other #define values. We won't get into that stuff here, but if you're interested in this you can look at some examples here.


Paul Gribble | Summer 2012
This work is licensed under a Creative Commons Attribution 4.0 International License
Creative Commons License