Preprocessor Directives

I don’t touch upon preprocessor directives in deep detail in the book. The #include and #define directives are mentioned, but they’re only two of many preprocessor directives available in the C Language.

What’s a Preprocessor Directive?

A preprocessor directive is given to the compiler before the C code is compiled. The compiler works through the preprocessor directives first, making substitutions, inclusions, and even decisions before the source code is translated into object code.

Here are the various preprocessor directives:

#include
#define
#undef
#if
#endif
#elif
#else
#ifndef

The place you’ll see most of these directives used are in the various header files. In fact, I recommend you peruse the header files to explore the possibilities of how these directives are put to work. That’s because most of your code probably won’t use these guys.

#include

The #include directive brings in code from another file, typically a header file. The directive is followed by a filename. When the filename is enclosed in angle brackets:

#include

the compiler looks for that file in the /usr/include (or similar) directory. Otherwise, when the filename is enclosed in double quotes:

#include "project.h"

the file is looked for in the current directory.

#define

In the book, I describe how #define is used to create constants and make substitutions. It’s official definition is “macro substitution.” It creates shortcuts. When the compiler encounters this preprocessor directive, it works through the code and makes substations as necessary. For example:

#define ROWS 5

Above, the compiler would search for any instance of ROWS and replace it with the value 5.

You can include variables in the macro expansions, which is done for the definition of putchar() in the stdio.h header file

#define putchar(x) putc(x,stdout)

Be careful when making such expansions, however, as sometimes the compiler may expand the macro twice.

#undef

The #undef preprocessor directive un-defines something previously created by the #define directive. This is an example of a directive you’ll often find in a header file, but not necessarily in your code.

#if
#endif

The #if directive evaluates a condition. When the condition is true, the statements that follow #if are executed, up until the #endif directive. I’ve actually used this directive in my code a long, long time ago. I created a constant to determine whether the computer was capable of displaying color text or not:

#define COLOR 1

Later #if directives examined that constant to determine whether color information was compiled into the code or not:

#if COLOR
/* color code goes here */
#endif

Of course, I had to manually set the COLOR value. That was okay; it allowed me to use one source code file to generate two different versions of the program, one for color systems and one for monochrome.

Remember that the #endif directive is required to terminate a block of #if statements.

#elif
#else

These two directives correspond to else if and else items in an C language if decision tree. They allow you to construct complex decisions using preprocessor directives.

#ifdef
#ifndef

These directives form specific if conditions based on whether something is defined or not yet defined. The value of what’s defined doesn’t matter, just whether the item has been defined or not. For example:

#ifndef BLORFUS
#define BLORFUS 64
#endif /* BLORFUS */

The above example creates the constant BLORFUS if it hasn’t yet been defined. You’ll see lots of those examples inside the header files, if you choose to peruse them. Read my February 21 2015 Lesson for a specific example of how to use these directives.

Leave a Reply