Si une variable globale est initialisée à 0, ira-t-elle à BSS?

Toutes les variables globales / statiques initialisées iront à la section de données initialisée . Toutes les variables globales / statiques non initialisées iront à la section de données non initialisée (BSS). Les variables dans BSS recevront une valeur 0 pendant le temps de chargement du programme.

Si une variable globale est explicitement initialisée à zéro ( int myglobal = 0 ), où cette variable sera-t-elle stockée?

Le compilateur est libre de mettre cette variable dans bss ainsi que dans les data . Par exemple, GCC a une option spéciale contrôlant ce comportement:

-fno-zero-initialized-in-bss

Si la cible prend en charge une section BSS, GCC met par défaut les variables initialisées à zéro dans BSS. Cela peut économiser de l’espace dans le code résultant. Cette option désactive ce comportement car certains programmes reposent explicitement sur des variables allant à la section de données. Par exemple, afin que l’exécutable résultant puisse trouver le début de cette section et / ou émettre des hypothèses sur cette base.

La valeur par défaut est -fzero-initialized-in-bss .

Essayé avec l’exemple suivant (fichier test.c ):

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

Comstackr sans options (implicitement -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 

Compilation avec l’ -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 

Il est assez facile de tester un compilateur spécifique:

 $ 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 

Nous recherchons les emplacements 0000000000601028 et 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 

Il semble que les deux valeurs sont stockées dans la section .bss de mon système: gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4) .

Le comportement dépend de l’implémentation C. Il peut arriver que ce soit dans les fichiers .data ou .bss, et pour augmenter les modifications qui ne se retrouvent pas dans .data en prenant de l’espace redondant, il est préférable de ne pas l’initialiser explicitement à 0, car il sera de toute façon à 0 l’object est de durée statique.