为什么int类型在BSS部分占用8个字节,在DATA部分占用4个字节

Pen*_*ang 5 c linux gcc

我正在尝试学习C程序的可执行文件的结构.我的环境是GCC和64位Intel处理器.

请考虑以下C代码a.cc.

#include <cstdlib>
#include <cstdio>

int x;

int main(){
  printf("%d\n", sizeof(x));
  return 10;
}
Run Code Online (Sandbox Code Playgroud)

size -o a节目

 text      data     bss     dec     hex filename
 1134       552       8    1694     69e a
Run Code Online (Sandbox Code Playgroud)

我添加了另一个初始化的全局变量y.

int y=10; 
Run Code Online (Sandbox Code Playgroud)

size a节目(其中a从a.cc可执行文件的名称)

 text      data     bss     dec     hex filename
 1134       556      12    1702     6a6 a
Run Code Online (Sandbox Code Playgroud)

我们知道,该BSS部分存储未初始化的全局变量的大小并DATA存储已初始化的变量.

  1. 为什么int在BSS中占用8个字节?将sizeof(x)在我的代码表明,int实际占用了4个字节.
  2. int y=10添加4个字节数据,是有道理的,因为int应该采取4个字节.但是,为什么它会为BSS增加4个字节?

size删除两行后,两个命令之间的差异保持不变#include ....

更新: 我认为我对BSS的理解是错误的.它可能不存储未初始化的全局变量.正如维基百科所说:"BSS在运行时需要的大小记录在目标文件中,但BSS(与数据段不同)不会占用目标文件中的任何实际空间." 例如,即使是一行C代码int main(){}也有bss 8.

BSS的8或16是否来自alignment

Ada*_*eld 9

它没有,它占用4个字节而不管它在哪个段.你可以使用nm带有-S参数的工具(来自GNU binutils包)来获取目标文件中所有符号的名称和大小.您可能会看到编译器的次要影响,包括或不包括某些其他符号,无论出于何种原因.

例如:

$ cat a1.c
int x;
$ cat a2.c
int x = 1;
$ gcc -c a1.c a2.c
$ nm -S a1.o a2.o

a1.o:
0000000000000004 0000000000000004 C x

a2.o:
0000000000000000 0000000000000004 D x
Run Code Online (Sandbox Code Playgroud)

一个目标文件具有x在未初始化数据段(C)中命名的4字节对象,而另一个目标文件具有x在初始化数据段(D)中命名的4字节对象.