3

While using header files, each header file should be included only once.
For example, lets say I have three classes. class A, class B and class C.

class A is declared in the file A.h, class B is declared in the file B.h and class C is declared in the file C.h, and they are defined in their respective .cpp files.
A.cpp

#include "A.h"
class A  
{  
}  

In the B.cpp file, the following will be the definition of the class.

#include "A.h"
#include "B.h"
class B  
{  
   A a;
}

And same goes for the C.cpp file as well.

#include "A.h"
#include "B.h"
#include "C.h"
class C  
{  
  A a;  
  B b;  
}  

Now, if include guards are not written in the header files, then the g++ compiler will throw an error.
My question is, why should we need to specify the include guards? Is it not common sense that each header file should be included only once? Why doesn't the compiler take care of multiple includes by itself?

HDJEMAI
  • 9,436
  • 46
  • 67
  • 93
Rohit Shinde
  • 1,575
  • 5
  • 21
  • 47
  • 3
    Because there are times when you *do* want a header file included more than once. – Benjamin Lindley Oct 26 '14 at 04:18
  • 2
    Can you give an example? – Rohit Shinde Oct 26 '14 at 04:20
  • I think that is because the `#include ` stuff is first handle by the preprocessor, which basically puts the contents of the header file in your main file, and so what the compiler sees is a lot of repeated code. – rendon Oct 26 '14 at 04:27
  • 1
    Here's an SO post that addresses the question of why `#include`ing a file multiple times is useful. http://stackoverflow.com/questions/10877494/including-header-files-in-c-c-more-than-once – R Sahu Oct 26 '14 at 04:42

3 Answers3

3

As its been said, sometimes you do want an include file to be invoked more than once; and there may be many situations where this is desirable.

One example where this comes in useful is for optimizing instantiations of large, complicated templates. Consider some typical large, complicated template class

template<typename T> class ComplicatedTemplate {

// ... Boring stuff goes here

};

Having this large template instantiated and compiled in every translation unit, for the same template type, over and over again, gets really old. It slows down a compile, and needlessly bloats every object module, only to have the linker deal with stripping out a ton of duplicate template instantiations. It's a lot of wasted work.

Many compilers offer ways to control template instantiations. The exact details can vary, sometimes, but I'll use the typical approach, as used by gcc, which you can read about here:

https://gcc.gnu.org/onlinedocs/gcc/Template-Instantiation.html

Say, you'd want to burn some CPU time instantiating ComplicatedTemplate<std::vector<int>>, ComplicatedTemplate<std::vector<char>>, maybe ComplicatedTemplate<std::string<std::string>> in some translation unit called "complicated.cpp", and just declare them extern in the header file.

Ok, so you end up with this in complicated_template.H

template<typename T> class ComplicatedTemplate {

// ... Boring stuff goes here

};

extern template ComplicatedTemplate<std::vector<int>>;
extern template ComplicatedTemplate<std::vector<char>>;
extern template ComplicatedTemplate<std::vector<std::string>>;

Then, in complicated.cpp:

#include "complicated_template.H"

template ComplicatedTemplate<std::vector<int>>;
template ComplicatedTemplate<std::vector<char>>;
template ComplicatedTemplate<std::vector<std::string>>;

Ok, so that's going to work fine, except for one inconvenience. If you decide to also add ComplicatedTemplate<std::vector<SomeCustomType>>, or anything else, to the list of pre-instantiated templates, this needs to be done in two places; both in the header file, and in complicated.cpp

Here's a typical approach that eliminates this duplication:

complicated_template.H:

template<typename T> class ComplicatedTemplate {

// ... Boring stuff goes here

};

#include "complicated_template_inst.H"

complicated_template_inst.H:

#ifndef EXTERN
#define EXTERN
#endif

EXTERN template ComplicatedTemplate<std::vector<int>>;
EXTERN template ComplicatedTemplate<std::vector<char>>;
EXTERN template ComplicatedTemplate<std::vector<std::string>>;

Then, in complicated.cpp:

#include "complicated_template.H"
#define EXTERN
#include "complicated_template_inst.H"

Now, the list of template instances that get pre-instantiated is in one place. Using the earlier example, adding:

EXTERN template ComplicatedTemplate<std::vector<SomeCustomType>>;

has the effect of both preventing the wasted instantiation of this template in every translation unit that needs that template instance, and of instantiating it explicitly in the complicated.cpp translation unit.

You will see this kind of an approach in many large C++ libraries. They will typically define their templates, then pre-instantiating them by pulling in a separate #include file, that contains some preprocessor-fu. The actual shared library will also include the second file a second time, after pulling in the externally-visible header file, with the preprocessor accordingly rigged up to turn those extern template declarations into template instantiations.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
3

My question is, why should we need to specify the include guards? Is it not common sense that each header file should be included only once? Why doesn't the compiler take care of multiple includes by itself?

Because it's not true for all headers. One example of a header that can be included more than once, and being able to do so actually matters, is the <assert> header.


There's not really any point to trying to fix up the header system of copying and pasting file contents. Really we just need to move to a better build model.

bames53
  • 86,085
  • 15
  • 179
  • 244
0

We usually think of the compilation as a single step, but actually there are various steps involved, in the case of C++, one of those phases is the preprocessing, which handles the #include <header.h> stuff, which basically puts the contents of each header file (and also things like #define) in your main file, so, if you do not make the appropriate conditions your main source file will end up with repeated code.

For example, let's say you have two files:

// a.h
class A {

};

And

// b.cpp
#include "a.h"
#include "a.h"

int main()
{
    return 0;
}

Before the actual compilation b.cpp will be processed by the preprocessor, which using g++ the result is something like this:

# 1 "b.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "b.cpp"
# 1 "a.h" 1
class A {

};
# 2 "b.cpp" 2
# 1 "a.h" 1
class A {           // Repeated code

};
# 3 "b.cpp" 2

int main()
{
    return 0;
}

And this last code is what the compiler works on. At this point the compiler can't help too much.

This is a very simplistic example but I think it can help you.

rendon
  • 2,323
  • 1
  • 19
  • 25
  • This answers the *what*, but it doesn't really answer *why*. – Jack Oct 26 '14 at 04:43
  • The question asked here is why the compiler doesn't already add the guards automatically. You've answered a completely different question -- why they're needed, but this is not the question that was asked. – Sam Varshavchik Oct 26 '14 at 04:44