Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 不初始化0的.bss部分如何_C_Gcc_Elf - Fatal编程技术网

C 不初始化0的.bss部分如何

C 不初始化0的.bss部分如何,c,gcc,elf,C,Gcc,Elf,正如我们所知,bss包含未初始化的变量。如果在c代码中,编程人员在使用变量之前初始化变量。那么,在执行C代码之前,bss不必为零 我说得对吗 感谢C代码中的,规范将任何具有静态存储持续时间的变量定义为初始化为0(第6.7.8节初始化,第10段): 如果没有显式初始化具有静态存储持续时间的对象,则: 如果有指针类型,则初始化为空指针 如果它有算术类型,则初始化为(正或无符号)零 如果是聚合,则根据这些规则(递归地)初始化每个成员 如果是联合,则根据这些规则(递归地)初始化第一个命名成员 一些程

正如我们所知,bss包含未初始化的变量。如果在c代码中,编程人员在使用变量之前初始化变量。那么,在执行C代码之前,bss不必为零

我说得对吗


感谢C代码中的

,规范将任何具有静态存储持续时间的变量定义为初始化为0(第6.7.8节初始化,第10段):

如果没有显式初始化具有静态存储持续时间的对象,则:

  • 如果有指针类型,则初始化为空指针
  • 如果它有算术类型,则初始化为(正或无符号)零
  • 如果是聚合,则根据这些规则(递归地)初始化每个成员
  • 如果是联合,则根据这些规则(递归地)初始化第一个命名成员
一些程序加载器将从零开始填充整个部分,而另一些程序加载器将“按需”填充它作为性能改进。因此,尽管您在技术上是正确的,
.bss
部分在C代码开始执行时可能并不真正包含所有零,但它在逻辑上确实包含所有零。在任何情况下,假设您有一个符合标准的工具链,您可以将其视为全部为零


任何初始化为非零值的变量永远不会出现在
.bss
部分;它们在
.data
.rodata
部分进行处理,具体取决于它们的特定特征。

这取决于变量在代码中的位置。例如,如果您在main()或任何其他函数中谈论局部变量,那么变量将被推送到堆栈上(除非您使用其他修改关键字)。如果您的变量是全局变量且未初始化,则应将其保存在.bss中。请注意,编译器优化等可能会稍微改变一些情况。如果您确实想知道,请使用readelf来调查linux上的ELF二进制文件

ELF规范规定:

.bss此节保存未初始化的 有助于程序运行的数据 内存映像。顾名思义 系统用零初始化数据 当程序开始运行时。这个 节不占用任何文件空间,如下所示 由截面类型指示, 小诺比茨


因此,分配了值的C全局变量不能放入.bss部分,而必须放入.data部分。.data部分包含分配给它的所有变量的初始值。

您可能会对.bss部分最终初始化为零的机制感到困惑。您编译的代码不必显式地将区域初始化为零,因为当操作系统首次向进程分配新的内存页时,操作系统会确保该页已初始化为零。这样做是出于安全原因,因此进程无法查找在其他进程退出时留在内存中的机密。

任何静态存储持续时间显式初始化为0的变量也可能最终出现在.bss部分。您假设代码由操作系统运行,但实际情况并非如此,这就是为什么当某些变量需要取消初始化时,它需要位于.bss中。因为,bss实际上是零填充的