C语言 结构中的组织变量是否有任何缺陷



有一个现有的C项目,有一些模块。每个模块都有一些全局变量和一些模块全局变量。我们有命名约定,例如MODULENAME_varname模块声明的全局变量和模块全局变量的Modulename_varname

如果我想为相应的全局和模块全局变量引入结构,我可以期待任何麻烦

吗?
struct{
 int  moduleId;
 type1 member1;
 type2 member2;
 ...
} MODULE

struct{
 int  moduleId;
 type1 member1;
 type2 member2;
 ...
} Module

我更喜欢这样,而不是拥有一堆非结构化变量。这个想法是例如使用IDE列出所有成员变量以提高舒适度,或者只是使用某种意义上的函数

log(MODULE.moduleId,offset(MODULE,member1))

它可以增加RAM和程序代码的内存使用量。

结构填充

大多数体系结构要求变量以某种方式对齐。例如,32 位变量可能必须与可被 4 整除的地址对齐才能进行有效访问。

结构成员必须按声明顺序排列。这意味着编译器可能需要添加填充以保持数据访问速度。

struct { // Structure aligment is 4, to keep 'a' aligned
    uint32_t a;
    uint8_t b;
    // Compiler inserts 3 byte padding here to keep 'c' aligned
    uint32_t c;
    //... other data here
} Module;

编译器可以以节省空间的方式在内存中排列"自由"变量。对于结构,您需要手动执行此操作。通常,这是通过从大到小或相反对成员进行排序来完成的。

请注意,许多编译器提供的结构打包不是解决方案。它通常会降低性能和/或增加程序大小。

可变放置

我正在简化这一点,但是:

通常,全局变量分为 2 组:零初始化和值初始化(零除外(。在启动 main 之前,必须初始化这两个。

对于零初始化变量,链接器通常只是将它们组合在一个位置,然后在调用 main 函数之前执行一个大memset以将该区域中的所有字节设置为零。

值初始化的变量同样分组在其他位置,然后在程序启动时完成一个大memcpy,从变量上的程序内存(按相同顺序排列(复制初始值。

如果将所有变量组合到结构中,则如果任何值不为零,则会强制从程序内存中复制所有初始值。


如果您在台式计算机上,这些可能不是问题。但是,在内存紧张的嵌入式系统上,必须考虑这些。

请注意,我并不是说这是一个坏主意。只要保持结构模块化,避免大型整体结构。

最新更新