【问题标题】:Why gcc garbage collection behave differently for initialized global variables and uninitialized global variables?为什么 gcc 垃圾收集对于已初始化的全局变量和未初始化的全局变量的行为不同?
【发布时间】:2014-06-10 13:21:01
【问题描述】:

考虑以下程序:-

int busy[53] = { 1,2} ;
int barra[50]  = {4,5};

int main(void)
{
    int bb;
    while (1)
    {
        bb = barra[3];
    }
}

我使用带有参数“-Wl,--gc-sections -fdata-sections”的 gcc 编译上述程序,在调试时我发现编译器/链接器没有为数组繁忙分配任何内存,因为这个数组不是在应用程序中的任何地方使用,如果我在无限循环中删除该行,GC dint 也会为 barra 数组分配任何内存。

然后我更改了相同的程序,并使繁忙和巴拉未初始化的数组如下 -

int busy[53];
int barra[50];

现在我用相同的命令行参数编译了新程序(while 循环内有行),当我调试时,发现编译器/链接器为忙数组和 barra 数组分配了内存,而不仅仅是 barra。如果我在无限循环中删除该行并重新编译,GC dint 为两个数组分配任何内存,与初始化数组相同。

所以我很好奇为什么编译器/链接器/GC(不确定哪个在做)在程序中只使用一个数组时为两个未初始化的数组分配内存?

相同情况的初始化数组按预期工作,因为它只为程序中使用的数组分配内存。

这是 bss 中变量的错误还是一些调整?

使用 GCC - 4.9.0 20140319

【问题讨论】:

  • 值得注意的是,优化器不是垃圾收集器,它们是不同的概念。
  • @Happington 但它也可以看作是垃圾收集。尽管该术语通常用于内存清理,但图像也适用于此。

标签: c arrays gcc garbage-collection


【解决方案1】:

我只能猜测,但可能-fdata-sections 仅适用于“真实”数据部分,不适用于 bss 部分。

本质上,

int busy[53] = { 1,2} ;
int barra[50]  = {4,5};

int ubusy[53];
int ubarra[50];

将每个busybarra 放入自己的部分,但仍会创建一个包含ubusyubarra 的bss 部分。

链接器因此看到busy 未被使用并丢弃它,但bss 被使用(即使不是全部)并因此被保留。

【讨论】:

  • 虽然可能,您是否真的尝试过编译 OP 的代码?我无法复制 ubusy 和 ubarra 都被分配的行为。每次我编译它(正确)只分配给 ubarra。
  • 忽略,这与我的 gcc 设置有关。
  • 当检查生成的地图文件(-Wl,Map=name.map)时,ubusy和ubarra(uninit变量)存储在一个名为Common的部分中,如你所说。我们可以称之为编译器错误吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多