Main Content

MISRA C:2023 Dir 4.10

Precautions shall be taken in order to prevent the contents of a header file being included more than once

Since R2024a

Description

Directive Definition

Precautions shall be taken in order to prevent the contents of a header file being included more than once.

Rationale

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.

Polyspace Implementation

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 using several methods. For instance, use the preprocessor directives ifdef or ifndef as include guards :

<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>

Troubleshooting

If you expect a rule violation but do not see it, refer to Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

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.

#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 func(void) is outside the guard.

Note

You can have comments outside the 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 name in the #ifndef statement is different from the name in the following #define statement.

#ifndef  __MY_MACRO__ 
#define __MY_MARCO__
    void func(void);
    void func2(void);
#endif

You can use a branched inclusion guard structure to protect against multiple inclusion:

#ifndef FOO
#define FOO 1
#else
#undef FOO
#define FOO 2 
/*...Code content */
#endif
Such inclusion guards are compliant with this rule.

Check Information

Group: Code Design
Category: Required
AGC Category: Required

Version History

Introduced in R2024a