La raison est de réduire la taille du programme. Imaginez que votre programme C s'exécute sur un système embarqué, où le code et toutes les constantes sont enregistrés dans une véritable ROM (mémoire flash). Dans de tels systèmes, une "copie vers le bas" initiale doit être exécutée pour définir tous les objets de durée de stockage statique, avant que main() ne soit appelée. Il ressemblera généralement à ce pseudo :
for(i=0; i<all_explicitly_initialized_objects; i++)
{
.data[i] = init_value[i];
}
memset(.bss,
0,
all_implicitly_initialized_objects);
Où .data et .bss sont stockés dans la RAM, mais init_value est stocké dans la ROM. S'il s'agissait d'un segment, la ROM devait être remplie de nombreux zéros, ce qui augmentait considérablement la taille de la ROM.
Les exécutables basés sur la RAM fonctionnent de la même manière, bien qu'ils n'aient bien sûr pas de véritable ROM.
De plus, memset est probablement un assembleur en ligne très efficace, ce qui signifie que la copie de démarrage peut être exécutée plus rapidement.
Le .bss
segment est une optimisation. L'ensemble .bss
segment est décrit par un nombre unique, probablement 4 octets ou 8 octets, qui donne sa taille dans le processus en cours, alors que le .data
section est aussi grande que la somme des tailles des variables initialisées. Ainsi, le .bss
rend les exécutables plus petits et plus rapides à charger. Sinon, les variables pourraient être dans le .data
segment avec initialisation explicite à zéro ; le programme aurait du mal à faire la différence. (En détail, l'adresse des objets en .bss
serait probablement différente de l'adresse si elle était dans le .data
segment.)
Dans le premier programme, a
serait dans le .data
segment et b
serait dans les .bss
segment de l'exécutable. Une fois le programme chargé, la distinction devient sans importance. Au moment de l'exécution, b
occupe 20 * sizeof(int)
octets.
Dans le deuxième programme, var
est alloué l'espace et l'affectation en main()
modifie cet espace. Il se trouve que l'espace pour var
a été décrit dans le .bss
segment plutôt que le .data
segment, mais cela n'affecte pas le comportement du programme lors de son exécution.