gcc 使用全局数组的数据段大小

xvw2m8pv  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(120)

我有一个代码,有几个未初始化的全局变量,为了简单起见,让我们说3:

int global_uninitialized_0;
int global_uninitialized_1;
int global_uninitialized_2;

在编译这段代码时,size报告的大小是16。
如果我添加了更多的全局未初始化变量,则函数将按预期增长。然而,如果我使用一个int数组,它的增长比我预期的要多:

int global_uninitialized_0;
int global_uninitialized_1;
int global_uninitialized_2[4];

在编译这段代码时,size报告的大小是48。请注意,当使用一个3个元素的数组时,数组也会按预期增长。
为什么会出现这种差异?我想说有某种联系,但我找不到任何相关的东西。

uinbv5nw

uinbv5nw1#

在编译x86_64的测试时,我观察到以下布局:

readelf -Ws t.o | grep ' global'
     2: 0000000000000000     4 OBJECT  GLOBAL DEFAULT    3 global_uninitialized_0
     3: 0000000000000004     4 OBJECT  GLOBAL DEFAULT    3 global_uninitialized_1
     4: 0000000000000010    16 OBJECT  GLOBAL DEFAULT    3 global_uninitialized_2

.bss的大小(这里是32个字节)非常合理,因为global_uninitialized_2从16个字节开始进入.bss部分,所以问题是:为什么编译器决定在global_uninitialized_1global_uninitialized_2之间留下一个8字节的漏洞?
我猜测GCC试图在16字节的边界上对齐这个数组,以实现缓存对齐的目的。
如果您将global_uninitialized_2的定义更改为仅需要4字节对齐:

__attribute__((aligned(4))) int global_uninitialized_2[4];

然后你会得到一个24字节的.bss,数组会在单个int之后立即分配。

相关问题