Wenn eine globale Variable auf 0 initialisiert wird, geht sie dann zu BSS?
Lesezeit: 2 Minuten
Alle initialisierten globalen/statischen Variablen gehen zu initialisierter Datenabschnitt. Alle nicht initialisierten globalen/statischen Variablen gehen zu nicht initialisierter Datenabschnitt(BSS). Die Variablen in BSS erhalten während der Programmladezeit den Wert 0.
Wenn eine globale Variable explizit auf Null initialisiert wird (int myglobal = 0), wo diese Variable gespeichert wird?
Was passiert, wenn Sie es versuchen? Sie können sehen, was in a ist .o Datei verwenden objdump -x.
– Greg Hewgill
4. Januar 2012 um 2:54 Uhr
Ich habe es unter A) versucht. for int globalvar = 0 ; objdump -x test > 1.txt B).for ==> int globalvar; objdump -x test > 2.txt Und der Unterschied ist: – 2 .bss 00000004 00000000 00000000 00000058 22 + 2 .bss 00000000 00000000 00000000 00000058 22 -00000000 g O .bss 00000004 globalvar +00000004 O KOM 00000004 Globalvar
– Mondpilze
4. Januar 2012 um 3:07 Uhr
@LunarMushrooms Update-Beitrag Hm 🙂
– Benutzer166390
4. Januar 2012 um 3:30 Uhr
Eldar Abusalimow
Der Compiler kann eine solche Variable frei einfügen bss sowie hinein data. Zum Beispiel hat GCC a besondere Option Kontrolle eines solchen Verhaltens:
-fno-zero-initialized-in-bss
Wenn das Ziel einen BSS-Abschnitt unterstützt, fügt GCC standardmäßig Variablen, die auf Null initialisiert werden, in BSS ein. Dies kann Platz im resultierenden Code sparen. Diese Option schaltet dieses Verhalten aus, da einige Programme explizit auf Variablen angewiesen sind, die in den Datenabschnitt gehen. ZB damit die resultierende ausführbare Datei den Anfang dieses Abschnitts finden und/oder darauf basierende Annahmen treffen kann.
Die Voreinstellung ist -fzero-initialized-in-bss.
Versucht mit folgendem Beispiel (test.c Datei):
int put_me_somewhere = 0;
int main(int argc, char* argv[]) { return 0; }
Kompilieren ohne Optionen (implizit -fzero-initialized-in-bss):
$ 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
Kompilieren mit -fno-zero-initialized-in-bss Möglichkeit:
$ 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
Es ist einfach genug, für einen bestimmten Compiler zu testen:
$ 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
Wir suchen den Standort von 0000000000601028 und 000000000060102c:
$ 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
Es sieht so aus, als ob beide Werte in der gespeichert sind .bss Abschnitt auf meinem System: gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4).
Das Verhalten ist abhängig von der C-Implementierung. Es kann entweder in .data oder .bss enden, und um Änderungen zu erhöhen, die nicht in .data enden und redundanten Speicherplatz beanspruchen, ist es besser, es nicht explizit auf 0 zu initialisieren, da es sonst sowieso auf 0 gesetzt wird Objekt ist von statischer Dauer.
Diese Frage ist mit GCC gekennzeichnet (obwohl die Version/das Ziel nicht angegeben ist).
– Benutzer166390
4. Januar 2012 um 3:31 Uhr
13712900cookie-checkWenn eine globale Variable auf 0 initialisiert wird, geht sie dann zu BSS?yes
Was passiert, wenn Sie es versuchen? Sie können sehen, was in a ist
.o
Datei verwendenobjdump -x
.– Greg Hewgill
4. Januar 2012 um 2:54 Uhr
Ich habe es unter A) versucht. for int globalvar = 0 ; objdump -x test > 1.txt B).for ==> int globalvar; objdump -x test > 2.txt Und der Unterschied ist: – 2 .bss 00000004 00000000 00000000 00000058 22 + 2 .bss 00000000 00000000 00000000 00000058 22 -00000000 g O .bss 00000004 globalvar +00000004 O KOM 00000004 Globalvar
– Mondpilze
4. Januar 2012 um 3:07 Uhr
@LunarMushrooms Update-Beitrag Hm 🙂
– Benutzer166390
4. Januar 2012 um 3:30 Uhr