Page 127 - C-Language
P. 127
#ifdef statements that check that the required headers are included in the proper order.
One advantage of the alternate design is that the #include list in the body file is exactly
the dependency list needed in a makefile, and this list is checked by the compiler. With
the standard design, a tool must be used to generate the dependency list. However, all
of the branch recommended development environments provide such a tool.
A major disadvantage of the alternate design is that if a unit’s required header list
changes, each file that uses that unit must be edited to update the #include statement
list. Also, the required header list for a compiler library unit may be different on different
targets.
Another disadvantage of the alternate design is that compiler library header files, and
other third party files, must be modified to add the required #ifdef statements.
Thus, self-containment means that:
• If a header header.h needs a new nested header extra.h, you do not have to check every
source file that uses header.h to see whether you need to add extra.h.
• If a header header.h no longer needs to include a specific header notneeded.h, you do not
have to check every source file that uses header.h to see whether you can safely remove
notneeded.h (but see Include what you use.
• You do not have to establish the correct sequence for including the pre-requisite headers
(which requires a topological sort to do the job properly).
Checking self-containment
See Linking against a static library for a script chkhdr that can be used to test idempotence and
self-containment of a header file.
Minimality
Headers are a crucial consistency checking mechanism, but they should be as small as possible.
In particular, that means that a header should not include other headers just because the
implementation file will need the other headers. A header should contain only those headers
necessary for a consumer of the services described.
For example, a project header should not include <stdio.h> unless one of the function interfaces
uses the type FILE * (or one of the other types defined solely in <stdio.h>). If an interface uses
size_t, the smallest header that suffices is <stddef.h>. Obviously, if another header that defines
size_t is included, there is no need to include <stddef.h> too.
If the headers are minimal, then it keeps the compilation time to a minimum too.
It is possible to devise headers whose sole purpose is to include a lot of other headers. These
seldom turn out to be a good idea in the long run because few source files will actually need all the
facilities described by all the headers. For example, a <standard-c.h> could be devised that
includes all the standard C headers — with care since some headers are not always present.
https://riptutorial.com/ 103

