☰
  • 首页
  • 规则分类
  • 项目介绍
search
•••

不应在头文件中使用静态声明

4.5 ID_staticInHeader
目录 › next › previous

头文件中由 static 关键字声明的对象、数组或函数,会在每个包含该头文件的翻译单元或模块中生成副本造成数据冗余,如果将静态数据误用作全局数据也会造成逻辑错误。

类的静态成员不受本规则限制。

示例:

// In a header file
static int i = 0;    // Non-compliant

static int foo() {   // Non-compliant
    return i;
}

在编译每个包含该头文件的源文件时,变量 i 和函数 foo 都会生成不必要的副本。

在头文件中实现的内联或模板函数中,也不应使用静态声明,如:

// In a header file
inline void bar() {
    static Type obj;   // Non-compliant
    ....
}

如果该头文件被不同的模块(so、dll、exe)包含,obj 对象会生成不同的副本,很可能造成逻辑错误。

另外,由 const 或 constexpr 关键字限定的常量也具有静态数据的特性,在头文件中定义常量也面对这种问题,基本类型的常量经过编译优化可以不占用存储空间(有取地址操作的除外),而对于非基本类型的常量对象或数组也不应在头文件中定义,建议采用单件模式,将其数据定义在 cpp 等源文件中,在头文件中定义访问这些数据的接口,如:

// In arr.h
using Arr = int[256];
const Arr& getArr();

// In arr.cpp
#include "arr.h"

const Arr& getArr() {
    static Arr a = {
        1, 2, 3, ....
    };
    return a;
}

在需要用到常量数组的地方调用 getArr 函数,即可获取该数组的引用,没有任何重复的数据产生,并可保证数组在使用之前被有效初始化。

相关

ID_unsuitableDeclaration

依据

ISO/IEC 9899:1999 6.2.2(3) ISO/IEC 9899:2011 6.2.2(3) ISO/IEC 14882:2003 3.5(3) ISO/IEC 14882:2011 3.5(3)
Copyright©2024 360 Security Technology Inc., Licensed under the Apache-2.0 license.