Rules:

4.2.a. There shall always be precisely one header file for each source file and they shall always have the same root name.

4.2.b. Each header file shall contain a preprocessor guard against multiple inclusion, as shown in the example below.6

4.2.c. The header file shall identify only the procedures, constants, and data types (via prototypes or macros, #define, and typedefs, respectively) about which it is strictly necessary for other modules to be informed.

           i. It is a preferred practice that no variable ever be declared (via extern) in a header file.

          ii. No storage for any variable shall be allocated in a header file.

4.2.d. No public header file shall contain a #include of any private header file.

Example:

#ifndef ADC_H
#define ADC_H
...
#endif /* ADC_H */

Reasoning: The C language standard gives all variables and functions global scope by default. The downside of this is unnecessary (and dangerous) coupling between modules. To reduce inter-module coupling, keep as many procedures, constants, data types, and variables as possible privately hidden within a module’s source file.

   See also What Belongs in a C .h Header File?:

   embeddedgurus.com/barr-code/2010/11/what-belongs-in-a-c-h-header-file/

Enforcement: These rules shall be enforced during code reviews.


Footnotes

[6] The preprocessor directive “#pragma once” has the same purpose but is non-portable.

Comments:

Owners of the 2008 or 2013 edition of the printed book should note that the words "defined" and "declared" were inadvertently swapped in the original phrasing of rules 4.2.c.i and 4.2.c.ii. The phrasing on this web page and in later print and PDF versions has been corrected to use those terms in a manner consistent with their formal meanings in the ISO C standards.