jollen.org

Jollen 的 Blog
Jollen's email: jollen # jollen.org
more:  Jollen's Training

.bss section:C 語言所種下的因

.作者:jollen/
.日期:January 10, 2007 10:44 PM


由於當初 C 語言標準提到「未初始化的全域變數(un-initialized global variables)其初始值為零(zero)」,所以得到的結果便是「程式執行時,必須將未初始化的全域變數都初始化成零」。

Linux 針對這種狀況的解決方式是「配置 zeroed pages 給 .bss section」,因此 un-initialized global variables 的值(value)便會為零。

註:Un-initialized global variables 會被編譯器放到 .bss section,可參考 Jollen 的「BSS Section 觀念教學」專欄。

此外,global variable 被初始化為零時,也會被 GCC 放到 .bss section 裡。所以,以下的寫法:

int foo;

main()
{
...
}

會等於:

int foo = 0;

main()
{
...
}

以上二種寫法都會讓 foo 被放到 .bss section。由此可知,以下二種狀況,變數都會被放在 .bss section:

1. 當 global variable 未被初始化時;
2. 或是 global variable 被初始化成零時。

-fno-zero-initialized-in-bss

如果(但是確實有這種應用場合)我們不想讓 variable 被放到 .bss section 呢?做法有二。第一種方式是「傳統做法」,程式設計師只要將 global variable 初始化為「非零」值即可,舉以下程式為例:

#include <stdio.h>

int foo = 1;

int main(void)

{

printf("foo is %d.\n", foo);

return 0;

}

將此程式編譯:

$ gcc -O2 -o bss bss.c

利用 objdump 來觀察後,會發現 foo 變數被 GCC 放到 .data section 裡了。這種做法是基於 coding 時的做法。

第二種做法是 GCC 3.4.x 後所支援的「-fno-zero-initialized-in-bss」最佳化選項。將程式修改如下:

#include <stdio.h>

int foo = 0;

int main(void)

{

printf("foo is %d.\n", foo);

return 0;

}

請特別留意,global variable 仍要做初始化,所以「foo」一定要做「assignment」為零值的動作。將程式編譯:

$ gcc -fno-zero-initialized-in-bss -O2 -o bss bss.c

GCC 會把 foo 放到 .data section。同樣可利用 objdump 來觀察。

良好的 Embedded Linux 程式寫作習慣

了解以上的觀念後,我要來說明一個重要的觀念。由於某些特定應用,或是 target 需要將變數放在 .data section 裡,因此若是 Embedded Linux 的應用,建議應對全域變數做初始化,例如:

int x;
int y;
int z;

int main(void)
{
...
}

應將這種傳統 C 的寫作習慣調整為:

int x = 0;
int y = 0;
int z = 0;

int main(void)
{
...
}

良好的習慣養成,未來將會得到許多好處。

這種寫法並非傳統 C 語言所講的「多此一舉」,應該以 Linux systems software 的角度來思考:這種寫法便能搭配 GCC 的「-fno-zero-initialized-in-bss」或是「-fzero-initialized-in-bss(預設)」選項,來決定 global variable 要放到 .bss section 或是 .data section。

Tags:

純手工打造說明:技術專欄文章為 Jollen 原創,內容皆為人工撰寫,無 AI 生成。轉載請註明出處與作者,並全文引用。轉載時請在文章開頭或結尾明顯處註明「本文出處:https://www.jollen.org,已取得原作者同意並授權使用。」
訂閱電子報:不定期 Jollen's Blog 精選文章隨 Moko365 電子報寄送;請透過 Moko365 電子報訂閱(可隨時取消)。

Copyright(c) 2001–2007 www.jollen.org. All rights reserved.
Last update: 2026-07-22