You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

为何ELF目标文件的.bss段无内容?相关概念疑问求解

嘿,我来帮你把.bss段的这个困惑掰明白~

先纠正一个关键误解

你之前对.bss段的描述有点偏差:.bss段其实是用来存放未初始化的全局变量和静态变量的,不是“已初始化但暂未使用”的数据。这是搞懂它的核心前提!

说说“内容”到底指什么

这里的“内容”,本质是变量的初始值数据。比如你定义了int global_num = 100;,这个100就是这个变量的“内容”——编译器会把这个初始值实实在在地写到可执行文件的.data段里,程序运行时加载.data段,变量就拿到了初始值100。

为什么.bss段没有“内容”?

原因很简单:效率和空间优化

.bss里的变量都是没有显式初始化的,按照C/C++等语言的标准,这些变量会被默认初始化为0(或者指针类型的NULL)。如果把这些全0的初始值都写到可执行文件里,那文件会平白无故变大很多——毕竟大量未初始化变量的话,全0数据是冗余的。

所以编译器和链接器做了个聪明的处理:只在可执行文件里记录.bss段需要占用的内存大小,而不写入任何实际的初始值数据。等程序被操作系统加载到内存时,系统会自动把.bss对应的内存区域全部清零,这样变量就自动获得了默认的0值,既省了磁盘空间,又完成了初始化。

举个代码例子更直观:

// 这个变量有明确的非0初始值,会被放到.data段,文件里会存下5这个值
int data_var = 5;
// 这个变量没有显式初始化,会被放到.bss段,文件里不会存任何初始值
int bss_var;
// 静态未初始化变量同样进.bss
static char static_bss_var;

另外补充一句:有些编译器会把显式初始化为0的变量(比如int zero_var = 0;)也优化到.bss段,因为和默认零值的效果一样,没必要占.data的空间——这算是额外的优化,但不影响.bss段的核心定义。

内容的提问来源于stack exchange,提问作者Richard

火山引擎 最新活动