Preprocessor – the #include Directive

Behaviour of the #include directive is the same in both C and C++.

Purpose

It is used to include / insert / copy paste the contents of the specified file into the current file.

Format

#include <file name>

or

#include "file name"

or

#include preprocessor tokens

All preprocessor directives begin with the # symbol. It must be the first character on the line or the first character on the line following optional white space.

Some early compilers flagged an error if # was not the first character on the line.

Spaces or tabs are permitted between the # and include, but not escape characters or other symbols or macros. The preprocessor removes whitespace and concatenates the # and include together.

The following are valid uses:

#include <stdio.h>
# include <stdio.h>
#include "my_file.h"
# /* comments are whitespace */ include "my_file.h"

The following are invalid uses:

// #\ is not a valid preprocessor directive
# \t include <stdio.h>
// #" is not a valid preprocessor directive
# "" include <stdio.h>

Use

The #include directive is used to insert the contents of the specified file into the current file.

Any file may be specified, although, typically, only header files are specified.

For example, you might have an application that performs image manipulation and the manipulation coefficients are stored in a table or matrix. Instead of embedding those coefficients directly in the source file, you could store them in a separate file and include that file as part of your compilation:

#include "coefficient_table.h"

I’ve also seen it used to chop up large source files into smaller chunks:

#include "source_part_1.c"
#include "source_part_2.c"
#include "source_part_3.c"

Form – #include <file name>

This form causes the compiler to search an implementation defined location (or locations) for the specified file. Typically, this location is where the compiler’s library header files are stored.

If the specified file is not found, an error is reported.

Form – #include “file name”

This form causes the compiler to search an implementation defined location (or locations) for the specified file. Typically, this location is where user header files are stored.

If the specified file is not found, the preprocessor retries the search as though the file name was specified using angle brackets <>. NOTE: this includes any characters found between the quotes, including angle brackets.

If the specified file is not found with this new search, an error is reported.

Form – #include preprocessor tokens

This form causes the preprocessor to process the tokens following the #include. If after processing, the result is not one of the first two forms, the program is malformed.

Typically, this is used to avoid having multiple conditional #include throughout source files:

For example, consider you compile for different language markets. The only difference are the strings and messages which are contained in separate files:

#ifdef ENGLISH
# include "english_strings.h"
#elif defined FRENCH
# include "french_strings.h"
#else
# include "german_strings.h"
#endif

This needs to be replicated in every file that needs to include one of the language files. Worse yet, if you add support for another language, you have to update all files containing this conditional #include. However, you could write the files to use a non-conditional #include and not worry about which header to #include:

#ifdef ENGLISH
# define STRINGS "english_strings.h"
#elif defined FRENCH
# define STRINGS "french_strings.h"
#else
# define STRINGS "german_strings.h"
#endif
.
.
.
#include STRINGS

Of course, you still have to include the file containing the macro STRINGS. In which case, why bother creating a macro when you could just #include a header file called strings.h that already does the necessary conditional:

#include "strings.h"

You could also use this form to allow passing file names via a macro defined at the command line or in your makefile.