I've heard that you should prefer writing internal include guards instead of external include guards.
I have searched around the internet but haven't found an answer to it.
This is a snippet of the book C++ Coding Standards by Herb & Andrei that shows an "external include guard":
Avoid using the obsolete external include guards advocated in older books:
#ifndef FOO_HJNCLUDED_ //NOT recommended
#include "foo.h"
#define FOO_HJNCLUDED_
#endif
Now, this leads to the question below:
Q:
What is an internal include guard and what is an external include guard? What's the difference between the two, and why is internal include guards preferred?
I would like that the answer also provide an example.
Edit: I ended up answering my own question.
In the C and C++ programming languages, an #include guard, sometimes called a macro guard, header guard or file guard, is a particular construct used to avoid the problem of double inclusion when dealing with the include directive.
Always write internal #include guards. Never write external #include guards.
Without a header guard, a code file could end up with multiple (identical) copies of a given type definition, which the compiler will flag as an error.
Header guards are designed to ensure that the contents of a given header file are not copied, more than once, into any single file to prevent duplicate definitions. This is a good thing because we often need to reference the contents of a given header from different project files.
Here's something I've seen that probably explains the comment.
Here, foo.h
is defining an "internal include guard" (shortened to simply "include guard" by most people since it's the traditional way of doing it).
// foo.h
#ifndef _FOO_H__
#define _FOO_H__
// ...
#endif // _FOO_H__
In contrast, bar.h
is using foo.h
's include guard outside of foo.h
. We can nickname this as an "external include guard".
// bar.h
#ifndef _BAR_H__
#define _BAR_H__
#ifndef _FOO_H__
#include "foo.h"
#endif
// ...
#endif // _BAR_H__
One (very large) project I worked on claimed that this increased compiling speed, but the claim is dubious as this seems to me like a trivial compiler optimization and I haven't seen any metrics to prove the claim. However, we did notice it was annoying to read when including multiple header files.
After a good digging around, I can now answer my own question.
The common idiom putting "include guards" around the content of header files being included:
header.h
#ifndef HEADER_H
#define HEADER_H
// Contents of include file
#endif
Therefore, the content of the header will be processed once even though the header is #include
ed multiple times.
This is known as an "internal include guard" because the guard is entirely internal to the header file.
However, there could be an issue with the above method if the compiler takes a simple approach, opening the file multiple times to check for "internal include guards" which could cause increased compile time in large projects.
header2.h
#ifndef HEADER_H
#include "header.h"
#endif
// Rest of header file goes here
The line: #ifndef HEADER_H
is still defined and checked internally in header.h
. But by checking it externally the compiler might avoid having to open the file at all.
It is only suggested to check externally when a header file is included from other header files.
The check is not necessary when included from a source file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With