主要内容

MISRA C:2025 Rule 8.5

R2026b

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

自 R2026b 起

描述

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

理由

通过在头文件中声明标识符,您可以在定义或使用该标识符的任何翻译单元中包含该头文件。在头文件中将声明模块化有助于保持以下方面之间的一致性:

  • 声明与定义。

  • 不同翻译单元中的声明。

此规则强制执行在头文件中声明外部对象或函数的做法。

Polyspace 实现

规则检查项会检查显式和隐式的 extern 声明(忽略暂定的定义)。检查项会标记以下变量或函数:

  • 在非头文件中声明为 extern 的变量或函数

  • 被多次声明的变量或函数,例如,在头文件和非头文件中各声明一次。

此检查项会:

  • 忽略编译器特定的、不可移植的函数声明覆盖方式,例如 pragma weak 或 __attribute__((weak))。

  • 忽略代码中未使用的 typedef 和函数声明。

  • 将重声明视为违规。例如,如果您在代码中声明了一个弱符号,之后又重声明该符号,Polyspace® 会报告违规。如果您不想修复此类违规,可以在结果或代码中添加注释,以避免再次被审查。请参阅:

故障排除

如果您预期会出现违规,但未看到该违规,请参阅诊断为何编码规范违规未按预期显示。

示例

全部展开

在此示例中,外部函数 func2() 的声明不合规,因为它出现在非头文件中。其他外部对象和函数的声明均出现在头文件中,符合此规则。要修复此问题,请在头文件中声明 func2()。

头文件:


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

源文件:


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

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

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

在此示例中,函数 func() 在 header1.h 中声明,并在 header2.h 中调用。在 module2.c 中,虽然包含了文件 header2.h,但未包含 header1.h,这可能是无意中造成的。由于 module2.c 中包含对 func() 的调用但不包含声明,编译器会在编译期间为该函数生成一个隐式声明。文件 module1.c 包含具有显式声明的 header1.h。同一个外部函数同时具有显式声明和隐式声明不符合此规则。Polyspace 会引发违规。Polyspace 会报告缺陷。在结果详细信息部分中,Polyspace 会标记:

  • header1.h 中的显式声明

  • module2.c 中触发创建隐式声明的函数调用。


                  //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)
{
}

要修复此违规,请在 module2.c 中包含文件 header1.h。

在此示例中,函数 func() 的声明位于头文件 header.h 中。源文件 module1.c 和 module2.c 包含对 func() 的调用,但并未包含该头文件,这可能是由于疏忽所致。因此,编译器创建了 func() 的两个隐式声明,从而导致违反了此规则。Polyspace 会报告违规。在结果详细信息部分中,Polyspace 会标记触发创建隐式声明的函数调用。


                  //header.h

extern void func(void);
 

                  //module1.c

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


                  //module2.c

void bar(void)
{
	func(); 
}

要修复此违规,请在 module1.c 和 module2.c 中包含文件 header.h。

检查信息

组:声明和定义
类别:必需
AGC 类别:必需
PQL 名称:std.misra_c_2025.R8_5

版本历史记录

在 R2026b 中推出


1 All MISRA coding rules and directives are © Copyright The MISRA Consortium Limited 2021.

The MISRA coding standards referenced in the Polyspace Bug Finder™ documentation are from the following MISRA standards:

  • MISRA C:2004

  • MISRA C:2012

  • MISRA C:2023

  • MISRA C:2025

  • MISRA C++:2008

  • MISRA C++:2023

MISRA and MISRA C are registered trademarks of The MISRA Consortium Limited 2021.