如果我們用readelf -s
看符號表中,我們可以看到:
$ readelf -s prog1.o
Symbol table '.symtab' contains 10 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS bss.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 3
4: 0000000000000000 0 SECTION LOCAL DEFAULT 4
5: 0000000000000000 0 SECTION LOCAL DEFAULT 6
6: 0000000000000000 0 SECTION LOCAL DEFAULT 7
7: 0000000000000000 0 SECTION LOCAL DEFAULT 5
8: 0000000000000004 4 OBJECT GLOBAL DEFAULT COM uninit <<<<
9: 0000000000000000 16 FUNC GLOBAL DEFAULT 1 main
我們看到,您uninit
符號(「變量」)就是在這個階段,一個「共同」的象徵。它尚未被「分配」給BSS。
見這個問題上「共同」符號的詳細信息:What does "COM" means in the Ndx column of the .symtab section?
一旦最終可執行相連,它將被放置在BSS與您預期。
您可以通過將-fno-common
標誌GCC繞過這個問題:
$ gcc -fno-common -c bss.c
$ size bss.o
text data bss dec hex filename
72 0 4 76 4c bss.o
相反,你可能標誌着uninit
爲static
。這樣,編譯器就會知道沒有其他.o
文件可以引用它,所以它不會是一個「通用」符號。相反,它會立即放入BSS,如你預期:
$ cat bss.c
static int uninit;
int main() {
uninit = 1;
return 0;
}
$ gcc -c bss.c
$ size bss.o
text data bss dec hex filename
72 0 4 76 4c bss.o
+1非常好的問題。 –
'void main()'?仍然? – Jens
是的,不知道是什麼驅使我寫這個。固定。 –