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

时间:2014-07-18 20:37:22

标签: 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;
}

size -o a显示

 text      data     bss     dec     hex filename
 1134       552       8    1694     69e a

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

int y=10; 

size a显示(其中a是来自a.cc的可执行文件的名称)

 text      data     bss     dec     hex filename
 1134       556      12    1702     6a6 a

众所周知,BSS部分存储未初始化的全局变量的大小,DATA存储已初始化的变量。

  1. 为什么int在BSS中占用8个字节?我的代码中的sizeof(x)显示int实际上占用了4个字节。
  2. int y=10向DATA添加了4个字节,这是有意义的,因为int应该占用4个字节。但是,为什么它会向BSS添加4个字节?
  3. 删除两行size后,两个#include ...命令之间的差异保持不变。

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

    BSS的8或16是来自alignment吗?

1 个答案:

答案 0 :(得分:9)

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

例如:

$ 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

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