Main Content

CERT C: Rec. PRE06-C

Enclose header files in an inclusion guard

Description

Rule Definition

Enclose header files in an inclusion guard.1

Polyspace Implementation

The rule checker checks for Contents of header file not guarded from multiple inclusions.

Examples

expand all

Issue

The issue occurs when you do not take precautions order to prevent the contents of a header file being included more than once.

If you include a header file whose contents are not guarded from multiple inclusion, the analysis raises a violation of this directive. The violation is shown at the beginning of the header file.

You can guard the contents of a header file from multiple inclusion by using one of the following methods:

//<start-of-file>
#ifndef <control macro>
#define <control macro>
    /* Contents of file */
#endif
//<end-of-file>
or
//<start-of-file>
#ifdef <control macro> 
#error ...
#else
#define <control macro>
    /* Contents of file */
#endif
//<end-of-file>
Unless you use one of these methods, Polyspace® flags the header file inclusion as noncompliant.

Risk

When a translation unit contains a complex hierarchy of nested header files, it is possible for a particular header file to be included more than once, leading to confusion. If this multiple inclusion produces multiple or conflicting definitions, then your program can have undefined or erroneous behavior.

For instance, suppose that a header file contains:

#ifdef _WIN64
   int env_var;
#elseif  
   long int env_var;
#endif
If the header file is contained in two inclusion paths, one that defines the macro _WIN64 and another that undefines it, you can have conflicting definitions of env_var.

Example - Code After Macro Guard
#ifndef  __MY_MACRO__ 
#define __MY_MACRO__
    void func(void);
#endif
void func2(void);

If a header file contains this code, it is noncompliant because the macro guard does not cover the entire content of the header file. The line void func2(void) is outside the guard.

Note

You can have comments outside the macro guard.

Example - Code Before Macro Guard
void func(void);
#ifndef  __MY_MACRO__ 
#define __MY_MACRO__
    void func2(void);
#endif

If a header file contains this code, it is noncompliant because the macro guard does not cover the entire content of the header file. The line void func(void) is outside the guard.

Note

You can have comments outside the macro guard.

Example - Mismatch in Macro Guard
#ifndef  __MY_MACRO__ 
#define __MY_MARCO__
    void func(void);
    void func2(void);
#endif

If a header file contains this code, it is noncompliant because the macro name in the #ifndef statement is different from the name in the following #define statement.

Check Information

Group: Rec. 01. Preprocessor (PRE)

Version History

Introduced in R2019a


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.