I am reading a book on Applied C++.
Include guards will prevent a header file from being included more than once during the compilation of source file. Your symbol names should be unique, and we recommend choosing the name based on the name of the file. For example, our file, cache.h contains this include guard.
#ifndef _cache_h_
#define _cache_h_
...
#endif // _cache_h_
Lakos describes using redundant include guards to speed up compilation. See [Lakos96]. For large projects, it takes times to open each file, only to find that the include guard symbol is already defined (i.e., the file has already been included). The effects on compilation time can be dramatic, and Lakos shows a possible 20x increase in compilation times when only standard include guards are used.
[Lakos96]: LargeScale C++ software design.
I don't have Lakos96 reference book to refer concept so asking help here.
My questions on above text is
What does author mean by " For large projects, it takes times to open each file, only to find that the include guard symbol is already defined" ?
What does author mean by "when standard include guards are used" ?
Thanks for your time and help.
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.
include guard (plural include guards) (programming) In C and C++, a preprocessor directive used in header files to prevent them from being included multiple times.
Header Guards in C++ are conditional compilation directives that help to avoid errors that arise when the same function or variable is defined more than once by the mistake of a programmer. According to C++, when a function or a variable is defined more than once, it yields an error.
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.
From C++ Coding Standards (Sutter, Alexandrescu)
Many modern C++ compilers recognize header guards automatically (see Item 24) and don't even open the same header twice. Some also offer precompiled headers, which help to ensure that often-used, seldom-changed headers will not be parsed often
So, I would consider those suggestions outdated (unless you are still using some very dated compiler).
As for your questions:
What is a redundant compile guard?
A naive compiler will reload the file every time it's included. To avoid that, put RedundantIncludeGuards around the include: header.h
#ifndef HEADER_H_
#define HEADER_H_
// declarations
#endif
foo.c
#ifndef HEADER_H_
#include "header.h"
#endif
read more here. Your reference claims that by doing so you can be as much as 20% faster during compilation than you would be if foo.c were only doing
#include "header.h"
I don't know what Lakos96 says, but I'm going to guess anyway...
A standard include guard is like:
#ifndef FOO_H_INCLUDED
#define FOO_H_INCLUDED
....
#endif
A redundant include guard is using the macro when including the file:
#ifndef FOO_H_INCLUDED
#include "foo.h"
#endif
That way the second time the foo.h
file is included, the compiler will not even search for it in the disk. Hence the speedup: imagine a large project, one single compilation unit may include foo.h
100 times, but only the first one will be parsed. The other 99 times it will be searched for, opened, tokenized, discarded by the pre-compiler and closed.
But note that that was in 1996. Today, GCC, to give a well known example, has specific optimizations that recognize the include guard pattern and makes the redundant include guard, well..., redundant.
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