2.11 — Header guards

The duplicate definition problem

In lesson 2.6 -- Forward declarations and definitions, we noted that a variable or function identifier can only have one definition (the one definition rule). Thus, a program that defines a variable identifier more than once will cause a compile error:

Similarly, programs that define a function more than once will also cause a compile error:

While these programs are easy to fix (remove the duplicate definition), with header files, it’s quite easy to end up in a situation where a definition in a header file gets included more than once. This can happen when a header file #includes another header file (which is common).

Consider the following academic example:




This seemingly innocent looking program won’t compile! Here’s what’s happening. First, main.cpp #includes square.h, which copies the definition for function getSquareSides into main.cpp. Then main.cpp #includes geometry.h, which #includes square.h itself. This copies contents of square.h (including the definition for function getSquareSides) into geometry.h, which then gets copied into main.cpp.

Thus, after resolving all of the #includes, main.cpp ends up looking like this:

Duplicate definitions and a compile error. Each file, individually, is fine. However, because main.cpp ends up #including the content of square.h twice, we’ve run into problems. If geometry.h needs getSquareSides(), and main.cpp needs both geometry.h and square.h, how would you resolve this issue?

Header guards

The good news is that we can avoid the above problem via a mechanism called a header guard (also called an include guard). Header guards are conditional compilation directives that take the following form:

When this header is #included, the preprocessor checks whether SOME_UNIQUE_NAME_HERE has been previously defined. If this is the first time we’re including the header, SOME_UNIQUE_NAME_HERE will not have been defined. Consequently, it #defines SOME_UNIQUE_NAME_HERE and includes the contents of the file. If the header is included again into the same file, SOME_UNIQUE_NAME_HERE will already have been defined from the first time the contents of the header were included, and the contents of the header will be ignored (thanks to the #ifndef).

All of your header files should have header guards on them. SOME_UNIQUE_NAME_HERE can be any name you want, but by convention is set to the full filename of the header file, typed in all caps, using underscores for spaces or punctuation. For example, square.h would have the header guard:


Even the standard library headers use header guards. If you were to take a look at the iostream header file from Visual Studio, you would see:

For advanced readers

In large programs, it’s possible to have two separate header files (included from different directories) that end up having the same filename (e.g. directoryA\config.h and directoryB\config.h). If only the filename is used for the include guard (e.g. CONFIG_H), these two files may end up using the same guard name. If that happens, any file that includes (directly or indirectly) both config.h files will not receive the contents of the include file to be included second. This will probably cause a compilation error.

Because of this possibility for guard name conflicts, many developers recommend using a more complex/unique name in your header guards. Some good suggestions are a naming convention of <PROJECT>_<PATH>_<FILE>_H , <FILE>_<LARGE RANDOM NUMBER>_H, or <FILE>_<CREATION DATE>_H

Updating our previous example with header guards

Let’s return to the square.h example, using the square.h with header guards. For good form, we’ll also add header guards to geometry.h.




After the preprocessor resolves all of the includes, this program looks like this:


As you can see from the example, the second inclusion of the contents of square.h (from geometry.h) gets ignored because SQUARE_H was already defined from the first inclusion. Therefore, function getSquareSides only gets included once.

Header guards do not prevent a header from being included once into different code files

Note that the goal of header guards is to prevent a code file from receiving more than one copy of a guarded header. By design, header guards do not prevent a given header file from being included (once) into separate code files. This can also cause unexpected problems. Consider:




Note that square.h is included from both main.cpp and square.cpp. This means the contents of square.h will be included once into square.cpp and once into main.cpp.

Let’s examine why this happens in more detail. When square.h is included from square.cpp, SQUARE_H is defined until the end of square.cpp. This define prevents square.h from being included into square.cpp a second time (which is the point of header guards). However, once square.cpp is finished, SQUARE_H is no longer considered defined. This means that when the preprocessor runs on main.cpp, SQUARE_H is not initially defined in main.cpp.

The end result is that both square.cpp and main.cpp get a copy of the definition of getSquareSides. This program will compile, but the linker will complain about your program having multiple definitions for identifier getSquareSides!

The best way to work around this issue is simply to put the function definition in one of the .cpp files so that the header just contains a forward declaration:




Now when the program is compiled, function getSquareSides will have just one definition (via square.cpp), so the linker is happy. File main.cpp is able to call this function (even though it lives in square.cpp) because it includes square.h, which has a forward declaration for the function (the linker will connect the call to getSquareSides from main.cpp to the definition of getSquareSides in square.cpp).

Can’t we just avoid definitions in header files?

We’ve generally told you not to include function definitions in your headers. So you may be wondering why you should include header guards if they protect you from something you shouldn’t do.

There are quite a few cases we’ll show you in the future where it’s necessary to put non-function definitions in a header file. For example, C++ will let you create your own types. These user-defined types are typically defined in header files, so the definition can be propagated out to the code files that need to use them. Without a header guard, your code files can end up with multiple identical copies of these definitions, which will cause a duplicate definition compilation error.

So even though it’s not strictly necessary to have header guards at this point in the tutorial series, we’re establishing good habits now, so you don’t have to unlearn bad habits later.

#pragma once

Many compilers support a simpler, alternate form of header guards using the #pragma directive:

#pragma once serves the same purpose as header guards, and has the added benefit of being shorter and less error-prone.

However, #pragma once is not an official part of the C++ language, and not all compilers support it (although most modern compilers do).

For compatibility purposes, we recommend sticking to traditional header guards. They aren’t much more work and they’re guaranteed to be supported on all compliant compilers.


Header guards are designed to ensure that the contents of a given header file are not copied more than once into any single file, in order to prevent duplicate definitions.

Note that duplicate declarations are fine, since a declaration can be declared multiple times without incident -- but even if your header file is composed of all declarations (no definitions) it’s still a best practice to include header guards.

Note that header guards do not prevent the contents of a header file from being copied (once) into separate project files. This is a good thing, because we often need to reference the contents of a given header from different project files.

Quiz time

Question #1

Add header guards to this header file:


Show Solution

2.12 -- How to design your first programs
2.10 -- Header files

319 comments to 2.11 — Header guards

  • Sampo

    Why are multiple (forward) declarations of functions allowed, but multiple declarations of variables are not? Specifically: "Note that duplicate declarations are fine, since a declaration can be declared multiple times without incident[.]" However program such as

    will fail with the error "'int x' : redefinition" while

    will exit with 0. I suppose functions are considered as a special case compared to variables?

    • Sampo

      To answer my own question: For variables the act of definition is the same as instantiating an identifier, i.e.

      means defining a variable. However for functions the function prototype (i.e. forward declaration) is just a declaration: defining a function requires writing its body.

  • deepak raj giri

    the exmaple of header guard with square.cpp square.h and main.cpp. one is not working.   its is working for one project file and not working for another one.. what the suck is happening.  why so.. explain it please.

  • Hits

    Hey, is there a specific reason why there was a header guard used in geometry.h if it only #includes square.h? wouldn't it make no difference since the header guard is already included in square.h?

    • Alex

      While technically it isn't needed in this example, it's good practice to always include one. It probably takes less time to do it than to consider whether you actually need to or not.

      • Hollowed

        Alex, wow you are still here after more than 9 years. I wish I could be like you, you are an inspiration and this course is amazing!. Better than a university could ever teach and this probably covers an entire year of university.

        Thank you, Alex

  • _Grin12_

    Header files do not get compiled, they will only get compiled when they're included (#include "Player.h")

    Then Preprocessor directories will run in the target(cpp) (with the included header file in it-> which has Preprocessor statement on it)

  • lordstark

    In the very first example of this chapter, there are three files
    square.h  geometry.h and main.cpp  beacause getsquaresides gets included in main.cpp twice it causes an error.
    Q] In case main did not include any header. And we compiled the program. Will linker give an error because the geometry.h includes square.h , and both square.h and geometry.h will have a defination of getsquaresides.

    • nascardriver

      Header files don't get compiled individually. They only get compiled as part of the source files that include them. The preprocessor (The part that handles includes) simply takes the entire text of included headers and copies it into the source file.

  • Mike

    Using the conditional compilation directives (#ifndef ... ) as the header guard doesn't work when disabling language extensions which was suggested as "best practice" in the first chapter. It gives the " C1004 unexpected end-of-file found" error. I wanted to know why.

Leave a Comment

Put all code inside code tags: [code]your code here[/code]