Main Content

MISRA C:2023 Rule 8.5

An external object or function shall be declared once in one and only one file

Since R2024a

Description

Rule Definition

An external object or function shall be declared once in one and only one file.

Rationale

Declaring an identifier in a header file enables you to include the header file in any translation unit where the identifier is defined or used. Modularizing the declarations in header files helps maintain consistency between:

  • The declaration and the definition.

  • The declarations in different translation units.

The rule enforces the practice of declaring external objects or functions in header files.

Polyspace Implementation

The rule checker checks explicit and implicit extern declarations (tentative definitions are ignored). The checker flags variables or functions:

  • Declared extern in a nonheader file

  • Declared multiple times, for instance, once in a header and once in a nonheader file.

This checker:

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

In this example, the declaration of external function func2() is noncompliant because it occurs in a nonheader file. The other external object and function declarations occur in a header file and comply with this rule. To fix this issue, declare func2() in a header file.

Header file:

/* header.h */
extern int var;
extern void func1(void);   /* Compliant */

Source file:

/* module.c */
#include "header.h"

extern void func2(void);   /* Noncompliant */

/* Definitions */
int var = 0;
void func1(void) {}

In this example, the function func() is declared in header1.h. In header2.h, the function is called. In module2.c, the file header2.h is included, but header1.h is not included, perhaps inadvertently. Because module2.c includes a call to func() but no declaration, the compiler generates an implicit declaration for the function during compilation. The file module1.c includes header1.h, which contains an explicit declaration. Having an explicit and an implicit declaration for the same external function is noncompliant with this rule. Polyspace raises a violation. Polyspace reports a defect. In the Result Details section, Polyspace flags :

  • The explicit declaration in header1.h

  • The function call in module2.c, which triggers the creation of the implicit declaration.

//header1.h
extern void func(void);
//header2.h

#define __STATIC_INLINE static inline

__STATIC_INLINE void Reset(void)
{
	//...
	func(); //Noncompliant
}
//module1.c
#include "header2.h"
#include "header1.h"

void foo(void)
{
}

//module2.c
#include "header2.h"

void bar(void)
{
}

To fix this violation, include the file header1.h in module2.c.

In this example, the declaration of the function func() is in the header header.h. The source files module1.c and module2.c contains calls to func(), but the header file is not included in these source files, perhaps by mistake. As a result, the compiler creates two implicit declaration of func(), causing a violation of this rule. Polyspace reports the violation. In the Result Details section, Polyspace flags the function calls that trigger the creation of the implicit declarations.

//header.h

extern void func(void);
 
//module1.c

void foo(void)
{
	func(); //Noncompliant
}

//module2.c

void bar(void)
{
	func(); 
}

To fix this violation, include the file header.h in module1.c and module2.c.

Check Information

Group: Declarations and Definitions
Category: Required
AGC Category: Advisory

Version History

Introduced in R2024a