据我所知,如果设置了 -fzero-initialized-in-bss
,则未明确初始化的静态变量(并且对于 GCC,即使是那些明确初始化为零的变量,默认情况下就是这种情况)通常存储在 BSS 段中。然而,当我尝试检查该行为时,这些变量似乎存储在通用数据部分(带有初始化的全局变量)中。如果我编译(使用 -O0
作为衡量标准)并运行:
#include <stdio.h>
#include <stdlib.h>
extern char etext, edata, end;
int i = 42;
int main(int argc, char* argv[])
{
static int j;
printf ("end of program (etext) = %10p\n",&etext);
printf ("end of initialized data (edata) = %10p\n",&end);
printf ("end of uninitialized data (end) = %10p\n",&end);
printf ("=====\n");
printf ("Value of i (initialized global) : %d\n",i);
printf ("Address of i : %10p\n",&i);
printf ("Value of j (static with no explicit initialization) : %d\n",j);
printf ("Address of i : %10p\n",&j);
return 0;
}
我得到输出:
end of program (etext) = 0x40067d
end of initialized data (edata) = 0x600af0
end of uninitialized data (end) = 0x600af0
=====
Value of i (initialized global) : 42
Address of i : 0x600ae0
Value of j (static with no explicit initialization) : 0
Address of i : 0x600ae8
所以i
和j
存储在连续的内存地址,在&etext
和&edata
之间,也就是常规数据部分。此外,如果我理解正确的话,&edata == &end
似乎意味着 BSS 是空的。
现在我意识到编译器把哪个变量放在哪里是一个实现选择,它产生的结果是正确的。但我只是想知道为什么我会出现这种行为,以及是否有办法告诉 gcc 明确地将此类变量放入 BSS(我在手册中没有看到任何明显的解决方案)。
最佳答案
您的代码有错误。您为 edata 和 end 都打印了 end
的地址,因此您当然假设 edata == end,但事实并非如此。
当我修复您的代码并运行它时,我得到:
end of program (etext) = 0x8048578
end of initialized data (edata) = 0x804988c
end of uninitialized data (end) = 0x8049894Value of i (initialized global) : 42
Address of i : 0x8049888
Value of j (static with no explicit initialization) : 0
Address of j : 0x8049890
很明显,j
位于 edata 和 end 之间的区域,而不是与 i
位于同一位置。
(gcc 5.2.1 20150911(Debian 5.2.1-17),32 位)
关于c - 为什么我不能在 BSS 中获取静态变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33167982/