Inclusion Guards

Just to clear up what we’re talking about, an inclusion guard looks like this:

#ifndef HEADER_FILE_H
#define HEADER_FILE_H

...//your header

#endif //HEADER_FILE_H

It consists of three preprocessor directives around the code of your header file.

Most IDEs add these for you automatically when you create a header, but it’s well worth having an appreciation of why they are there.

An inclusion guard simply stops your header file being included more than once in any program at compilation time.

I’ve already talked about how the preprocessor effectively copies an included header into a source file, so you can see immediately why you might want to prevent this from happening, even if it is for no other reason than to keep your compilation time down and your executable smaller!

The other reason you should use them is because they prevent you running into errors like this:

In file included from <file>.h:8:0,
from <file>.h:12,
from <file>.h:14,
from <file>.cpp:14:
<file>.h:16:7: error: previous definition of 'class ThisClass'

When you’re working on a small program with only a couple of files, you might be tempted to think you can skip using them, especially if you’re generating everything by hand. However, small programs don’t take long to grow, so for all but the simplest of cases, use inclusion guards. They will save you hours of time trying to work out an include tree that doesn’t result in the errors above.

What name should I use?

The simplest method (and the conventional one) is to use the capitalised name of the header file, changing the dot to an underscore. So MyClass.h will be MYCLASS_H (that’s an example – you’d never actually call a class MyClass, right?).

What about #pragma once?

#pragma once tells the compiler to only include a header once, so it effectively does the same job. But, as I mentioned before, pragmas are preprocessor directives that are specific to your compiler, so you shouldn’t depend on them. In fact, pragma once is now obsolete in gcc.

Why?

Well, firstly, you’re relying on a compiler to implement something you can effectively do quite simply yourself. Your next compiler might not do the job the same way (see below), or even at all, which would mean more work for you further down the line.

Secondly, how will the compiler ensure that you aren’t including the same file twice without a #define? It will have to judge by filename, or inode, or some other comparative algorithm to prevent duplicate inclusion. This is quite a difficult task – symbolic links and mounted filesystems can slip through this kind of detection and result in the exact errors that you are trying to avoid.

The beauty of inclusion guards is that they are 100% portable and 100% supported.

Anything else I need to know?

Nope. Just remember that your guards go outside ALL the content in your header, including other includes.

Hmm.

What I mean is: make sure your #include directives in your header appear inside the inclusion guard.

Then you’ll never have to worry about a circular include again.


4 Comments

  1. Posted 26 November 2014 at 13:50 | Permalink

    I think that correctly is this, isn’t?

    #ifndef HEADER_FILE_H
    #define HEADER_FILE_H

    ..//your header

    #endif //HEADER_FILE_H

  2. Posted 26 November 2014 at 15:58 | Permalink

    Yes! Mis-type, thanks 🙂

  3. Trevor Hickey
    Posted 20 December 2014 at 13:35 | Permalink

    #pragma once is certainly a vendor specific directive that is not a part of the C++ standaed. However, I don’t think GCC has deprecated it. There was a bit of talk about depreciation in the past, but I think it had to do with an optimization #pragma once was doing that caused issues. It has since been fixed. I use pragma once on gcc 4.9 when compiling for C++14, and it hasn’t given me any problems or warnings about depreciation.

    Thanks for these articles. They are very thorough, and well explained.

  4. Posted 20 December 2014 at 14:07 | Permalink

    Interesting. gcc 4.8.3 (running on Fedora) gives me a warning if I use #pragma once. Checking the gcc docs, it refers to it being obsolete here: https://gcc.gnu.org/onlinedocs/gcc-3.1/cpp/Obsolete-once-only-headers.html

    Thank you – I’m glad you found them useful.