ECE-1021

Preprocessor Directive - #include

(Last Mod: 27 November 2010 21:38:41 )

ECE-1021 Home



Objectives


Overview

The C programming language is highly modular - meaning that the elements that make up a finished program are generally broken up amongst many different files. This allows code to be reused for different programs very effectively and efficiently. But any given module has to have access to at least some elements of other modules in order for the compiler to function properly. Instead of having to type this information into each file that needs it - which is not only inconvenient but also prone to errors - we place the necessary information into "header" files and then use the #include directive to import the entire contents of the file into the present source code file as though it were physically present in the file starting at the line where the directive was located. The directive is removed at the same time.

Following the #include directive is the name of a file, including any extension, that is to be imported. The name must be delimited (i.e., enclosed) either by a pair of angled brackets or a pair of double-quotes. The location where the preprocessor will look for the file is determined by which of these two forms is used.


#include <filename>

Example:

#include <stdio.h> // Standard I/O Functions

In this case the file name, namely stdio.h, is contained within angled brackets. This particular file is one of many "header files" - hence the .h extension - that came with the compiler. For convenience sake, the group of header files included with the compiler are collectively referred to as "standard header files" to distinguish them from all of the rest which are usually referred to as "custom header files".

Each of the standard header files contain code that gives us access to a number of useful functions that are grouped together based on the purpose they serve. This particular one is known as the "Standard I/O Library" and by including it we gain access to many functions that allow us to interact with the screen, the keyboard, and files on the computer's disk.

By enclosing the file name in brackets we are telling the preprocessor where to look for the file. If enclosed by angled brackets, the preprocessor looks for the file in what are referred to as the "Standard Include Directories". At the time that the compiler was installed, standard header files were placed into one or more directories and the path information needed to locate them was stored as part of the configuration options for the compiler. The angled brackets merely tell the preprocessor to fetch that path list from the configuration information, that's all.


#include "filename"

Example:

#include <my_math.h> // Custom header file

The other option would be to enclose the filename within double quotation marks. These tell the compiler to first look in the current directory and, if it can't find the file there, it will then look in the standard include directories.


Documenting Header File Usage

After each #include directive is a comment that indicates which elements the present program uses from that library. This is not required by the C standard nor is it particularly common in general practice. The purpose is to document why particular header files have been included and, for people new to C, to help gain familiarity with what elements are accessed through which files. Only those elements actually used should be in these comments and header files that don't contain any elements being used should not be included.

What the Delimiters Don't Mean

The two different delimiters only tell the preprocessor where to look for the file - nothing else. As long as the preprocessor is able to find the file, its contents are irrelevant from the perspective of carrying out the directive. The entire contents of the file will be imported into the present source code file before passing it on to the compiler.

Many people mistakenly believe that the angle brackets indicate something special about the file itself or how it can be used. This is based on the fact that the angled brackets are only used with the standard header files. But this is merely a correlated observation due to the fact that the standard header files are usually only found in these directories and, similarly, the only header files located in these directories are usually the standard header files. 

Although not recommended, were you to place a custom header file in one of the standard include directories the angled brackets form of the directive would find it just fine. Similarly, using double quotes around a standard header file will also locate it, provided a file with the same name isn't sitting in the current directory - which is why we don't simply place double quotes around all header file names.

Similarly, there is nothing magical about the file extension. The use of a single h for a C header file (and hpp for a C++ header file) is merely customary.


Handling of Explicit Path Information

In most implementations of C (not all - it is an implementation-defined behavior) you can also include path information along with the filename. In the case of TurboC/C++ v4.5, the type of bracket becomes irrelevant as only the path provided will be searched for the specified file. If the path is a relative path, then the starting point is the directory where the file containing the #include directive is located. Again, this is behavior that is specific to a given compiler.