具有常量对象的代码大小

Code size with const objects

本文关键字:代码 对象 常量      更新时间:2023-10-16

我有几个源文件,其中需要一些const变量。
在提供的框架中,有一个.hpp头文件,其中包含这些变量的定义(不仅是声明),并且此标头包含在我前面提到的源文件中。
然后我意识到,我的每个源文件都包含该 RO 数据const变量的副本,因此为了减少内存占用(我正在开发 ebdedded 系统),我又制作了一个 .hpp,它包含在我的源文件中,其中包含对这些变量的extern引用(包含在其他地方)。
我比较了构建 .o 对象信息,发现当将 .hpp 与 extern 引用一起使用时,代码大小和 RO 数据大小更大,而不是与实际变量的定义一起使用。
为什么?

更新:我犯了错误。具体来说,这里是链接器映射文件的片段: (注:RW,ZI删除)
不使用外部
:代码:1192
(包括数据):84 RO数据:144

使用外部:代码:1392
(包括数据):216
RO数据:
144

但我的错误有更多的新问题而不是答案:

  1. 在这种情况下,为什么 RO(常量数据)大小没有改变?
  2. 此范围内的公司数据是什么?

当定义未extern时,编译器可以内联它们,因此它们直接存储在代码中的"立即加载"指令中。
(这称为"恒定折叠"。

使它们extern对编译器隐藏了定义,迫使它在编译期间存储值并生成代码以在运行时获取它们。

它们不存储在只读段中,因为它们需要在程序启动时初始化,因此必须是可写的。
只读段仅适用于永不更改的内容,例如字符串文本的内容。

基本类型且C++中没有外部链接的常量没有存储或地址,除非获取其地址。 相反,文本值将插入到代码中,就像键入其数值一样。 例如代码:

const NUM = 25 ;
int n1 = NUM ;
int n2 = NUM ;

将生成相同的代码,以:

int n1 - 25 ;
int n2 = 25 ;

这是因为插入文本值所需的指令比从只读内存复制该值所需的指令更少。

但是,如果您有代码:

const NUM = 25 ;
int* np = &NUM ;

那么NUM将被迫拥有存储。

当您将 const 声明为外部时,您是在说该值存在于其他位置,并且链接器将分配它。 编译器无法知道如果在单独的模块中定义它将具有的值,并且它无法知道其他模块是否会获取其地址,因此必须显式存储它 - 这使得只读数据空间更大,但也使代码空间更大。

虽然在函数或类作用域之外的常量变量C++具有隐式静态链接,但在 C 中,它们是隐式extern。 因此,您可能会发现,如果使用 C 编译,结果会有所不同。 对于互操作性,如果您在头文件中声明 const,那么明智的做法可能是static显式声明它,以确保两种语言的语义相同。