Including Other Files: #include

One of the most common uses of the preprocessor is to include other files in a piece of source code. File inclusion directives look like this:

#include <stdio.h>
#include "foo.h"

The preprocessor searches for the file named after the #include and replaces the #include statement with the full contents of that file. Generally this is useful for including common definitions of types and constants that you want to share across several source files.

Because files you include with #include will often be included in several source modules you must avoid writing statements in include files which actually define functions or variables. Type, enumeration and structure declarations, class declarations, external function and variable declarations are safe. So are preprocessor macro declarations. Function definitions and variable definitions are generally undesirable and may lead to duplicate definition errors at link time. Thus

  typedef int* pint_t;              /* Safe: type declaration */

  extern void foo (pint_t p);       /* Safe: external function declaration */

  struct bar
    int         nValue;
    struct bar* pNext;
  };                                /* Safe: structure declaration */

is quite reasonable as an include file. The following is not:

  int nGlobal;                      /* Unsafe: variable definition */

  int foo (int* p)                  /* Unsafe: function definition */
    *p += nGlobal;

  struct bar
    int         nValue;
    struct bar* pNext;
  } barShared;                      /* Unsafe: variable definition */

Files which contain type definitions, external function and variable declarations and such meant to be included in several source files generally have the extension .h. For C++ sometimes such files are given the extension .hpp or no extension at all (the standard C++ system header files have no extension).

The difference between the <> form and the "" form of #include is that the <> form looks for 'system' includes. It does not search in the same directory as the source file being compiled. The "" form looks first in the same directory as the source file, and then, if it doesn't find the file, searches in the system include directories. See the section on the preprocessor in the introduction to GNU tools for information on how to control which directories are searched for include files.

Protecting Files from Multiple Inclusion

As a project grows it may become harder to keep track of which header files are actually being included by a piece of code. In the interests of making modules reasonably independent you may include certain header files for other modules in the shared header file definining the interface for that module. If you do this you will almost inevatibly end up with some piece of code which includes two headers for two modules it uses, but where each of those headers includes its own copy of a third header for a module used by both of those modules you are using. If this happens the same header file may be included twice (or more) in your source file. Unless you do something this may lead to errors as things are declared twice. It also wastes the compiler and preprocessor's time reading the same material twice.

Here is a simple strategy for preventing such problems using symbolic constants and conditional compilation.

For every header file include some directives like this:

#ifndef FOO_H
#define FOO_H

/* ... contents of header file ... */


The symbolic constant FOO_H should be different for each header file. A good strategy might be to use the name of the header file, and possibly add on the library or program name which the header is a part of.

With these directives the first time a header is included in a particular source file FOO_H will not be defined and the text inside the #if (including the definition of FOO_H) will be processed. The second time the header appears FOO_H will be defined and the text of the header will be skipped.