2012-01-04 22 views
20

所有已初始化的全局/靜態變量將轉至初始化數據段。 所有未初始化的全局/靜態變量將轉至未初始化的數據段(BSS)。在程序加載期間,BSS中的變量將獲得值0。如果一個全局變量被初始化爲0,它會去BSS嗎?

如果一個全局變量被明確初始化爲零(int myglobal = 0),其中變量將被保存?

+4

int put_me_somewhere = 0; int main(int argc, char* argv[]) { return 0; } 

不帶選項(隱含-fzero-initialized-in-bss)編譯什麼好開心當你嘗試它的時候?你可以使用'objdump -x'來查看'.o'文件中的內容。 – 2012-01-04 02:54:33

+0

我試過 A).for int globalvar = 0; objdump -x test> 1.txt B).for ==> int globalvar; objdump -x test> 2.txt 差異是: - 2 .bss 00000004 00000000 00000000 00000058 2 ** 2 + 2 .bss 00000000 00000000 00000000 00000058 2 ** 2 -00000000 g O。bss 00000004 globalvar +00000004 O * COM * 00000004 globalvar – 2012-01-04 03:07:29

+0

@LunarMushrooms更新信息* ahem * :) – 2012-01-04 03:30:41

回答

26

編譯器可以自由地把這種可變進bss以及成data。例如,GCC具有special option控制這種行爲:

-fno-zero-initialized-in-bss

如果目標支持BSS部,GCC默認把被初始化爲零到BSS的變量。這 可以節省生成的代碼中的空間。該選項會關閉此行爲,因爲某些程序明確依賴變量前往 數據部分。例如,使得生成的可執行文件可以找到該部分的開始部分和/或基於該部分做出假設。

默認爲-fzero-initialized-in-bss

試着用下面的例子(test.c文件):

$ touch test.c && make test && objdump -x test | grep put_me_somewhere 
cc  test.c -o test 
0000000000601028 g  O .bss 0000000000000004    put_me_somewhere 

編譯與-fno-zero-initialized-in-bss選項:

$ touch test.c && make test CFLAGS=-fno-zero-initialized-in-bss && objdump -x test | grep put_me_somewhere 
cc -fno-zero-initialized-in-bss test.c -o test 
0000000000601018 g  O .data 0000000000000004    put_me_somewhere 
+1

有趣的聲望,你有。 – 2012-01-04 03:22:20

+1

@EknathIyer我把它弄壞了:( – 2012-01-04 03:31:38

+0

dayummm,太糟糕了,Eldar – 2012-01-04 03:32:33

6

這是很容易測試一個特定的編譯器:

$ cat bss.c 
int global_no_value; 
int global_initialized = 0; 

int main(int argc, char* argv[]) { 
    return 0; 
} 
$ make bss 
cc  bss.c -o bss 
$ readelf -s bss | grep global_ 
    32: 0000000000400420  0 FUNC LOCAL DEFAULT 13 __do_global_dtors_aux 
    40: 0000000000400570  0 FUNC LOCAL DEFAULT 13 __do_global_ctors_aux 
    55: 0000000000601028  4 OBJECT GLOBAL DEFAULT 25 global_initialized 
    60: 000000000060102c  4 OBJECT GLOBAL DEFAULT 25 global_no_value 

我們正在尋找的0000000000601028000000000060102c位置:

$ readelf -S bss 
There are 30 section headers, starting at offset 0x1170: 

Section Headers: 
    [Nr] Name    Type    Address   Offset 
     Size    EntSize   Flags Link Info Align 
... 
    [24] .data    PROGBITS   0000000000601008 00001008 
     0000000000000010 0000000000000000 WA  0  0  8 
    [25] .bss    NOBITS   0000000000601018 00001018 
     0000000000000018 0000000000000000 WA  0  0  8 

它看起來像兩個值都存儲在.bss部分在我的系統上:gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4)

1

行爲取決於C實現。它可能以.data或.bss結尾,並且增加它不會以.data結尾的變化佔用多餘空間,最好不要將其明確初始化爲0,因爲無論如何它將被設置爲0對象是靜態持續時間。

+0

此問題標記爲GCC(雖然未指定版本/目標)。 – 2012-01-04 03:31:17