Protecting headers from double inclusion

For every variable and function in your C program, there is exactly one definition. If you try to supply two definitions of the same thing, you will get an error from the linker, ld, when you try to make your program. Declarations that are not definitions, on the other hand, can typically be repeated, and it is good style to keep things divided so that only declarations are in your headers (the .h files).

Nonetheless, some kinds of declarations cannot be repeated (notably, structures), so in general it would be a problem to include the same header twice. Obviously, nobody is going to just include the same header twice in a row.

#include "myheader.h"
#include "myheader.h"

However, headers often need to include each other—one header might create some type, and then another header might declare a function that returns a value of that type. So, if your code includes both headers, you have now included a header twice—once on purpose, and once implicitly by including another header. It would certainly be possible to solve this sort of problem by carefully documenting what other headers are included in every other header and making sure to include everything you need once and only once, but that would be as annoying as it sounds. Instead, programmers simply add some boilerplate code to their headers so that they are safely skipped if included a second time. (In programming terminology, including headers should be ‘idempotent’, i.e. doing it twice is harmlessly the same as doing it just once.)

We use preprocessor directives for that. Essentially, a ‘header guard’ such as this is an if statement, along the lines of ‘if this header has never been included before, go ahead and provide this code and mark that it has been included, but otherwise, just skip it’.

#ifndef WHATEVER_H
#define WHATEVER_H

/* Put all your declarations here. */

#endif

Typically, the #ifndef and #endif lines that delimit this conditional are the first and last lines of the file. It is safe to put whitespace and comments outside the conditional, but make sure all of your C code is inside it.

The WHATEVER_H symbol in the example is a unique identifier used to keep track of whether this particular header has been included before (if it hasn’t been defined, define it, etc.). You can choose whatever symbol you want, but every header needs its own unique one, so typically people choose something based on the file name itself. I encourage you to make all letters from the filename uppercase and delete all nonletter characters or replace them with underscores, so my-header.h would have a guard symbol like MY_HEADER_H.

You have attempted of activities on this page