Making Sure a Header File Gets Included Only Once

Problem

You have a header file that is included by several other files. You want to make sure the preprocessor scans the declarations in the header file no more than once.

Solution

#define a macro in your header file, and include only the contents of the header file if the macro hasn't already been defined. You can use this combination of the #ifndef, #define, and #endif preprocessor directives, as I did in Example 2-1:

#ifndef MYCLASS_H_ _ // #include guards
#define MYCLASS_H_ _

// Put everything here...

#endif // MYCLASS_H_ _

When the preprocessor scans this header file, one of the first things it will encounter is the #ifndef directive and the symbol that follows. #ifndef tells the preprocessor to continue processing on the next line only if the symbol MYCLASS_H_ _ is not already defined. If it is already defined, then the preprocessor should skip to the closing #endif. The line following #ifndef defines MYCLASS_H_ _, so if this file is scanned by the preprocessor twice in the same compilation, the second time MYCLASS_H_ _ is defined. By placing all of your code in between the #ifndef and #endif, you ensure that it is only read once during the compilation process.

Discussion

If you don't use this technique, which is called using include guards , you've probably already seen "symbol already defined" compilation errors that result from not taking a protective measure against multiple definitions. C++ does not allow you to define the same symbol more than once, and if you do (on purpose or by accident) you get a compilation error. Include guards prevent such errors, and they are pretty standard practice.

The macros you #define don't have to follow any particular format, but the syntax I used above is common. The idea is to use a symbol that won't conflict with another macro and cause your file to inadvertently be skipped during preprocessing. In practice, you may see other techniques, such as including a header file or module version in the macro, e.g., MYCLASS_H_V301_ _, or maybe even the author's name. It isn't that important how you name it, so long as you are consistent. These macros should only be referenced by the header file they are protecting, and nowhere else.

In some code you may see external include guards, which are the same as the internal include guards I described earlier, except that they appear in the file that is including the header file, not the header file itself:

#ifndef MYCLASS_H_ _
#include "myclass.h"
#endif

This short-circuits the inclusion process by not even including the file myclassh.h if the macro MYCLASS_H_ _ is already defined. External include guards were advocated several years ago to improve compile times for large projects, but compilers have improved and they are no longer necessary. Don't use them.

Even if you are working on a small project, it's a good idea to put include guards in your header files. If your header file is included by more than one other file, chances are you're going to get redefinition errors someday. Furthermore, small projects tend to turn into larger projects in a short amount of time, and while a project may have started off with a single executable and a set of header files that are only ever included once, sooner or later the project will grow and compilation errors will start to appear. If you add include guards from the beginning, you won't have to go back and add them to a bunch of files all at once sometime in the future.

Building C++ Applications

Code Organization

Numbers

Strings and Text

Dates and Times

Managing Data with Containers

Algorithms

Classes

Exceptions and Safety

Streams and Files

Science and Mathematics

Multithreading

Internationalization

XML

Miscellaneous

Index



C++ Cookbook
Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More
ISBN: 0596003943
EAN: 2147483647
Year: 2006
Pages: 241

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net