La razón es reducir el tamaño del programa. Imagine que su programa C se ejecuta en un sistema integrado, donde el código y todas las constantes se guardan en una verdadera ROM (memoria flash). En dichos sistemas, se debe ejecutar una "copia hacia abajo" inicial para establecer todos los objetos de duración de almacenamiento estático, antes de llamar a main(). Por lo general, será así:
for(i=0; i<all_explicitly_initialized_objects; i++)
{
.data[i] = init_value[i];
}
memset(.bss,
0,
all_implicitly_initialized_objects);
Donde .data y .bss se almacenan en RAM, pero init_value se almacena en ROM. Si hubiera sido un segmento, entonces la ROM tenía que llenarse con muchos ceros, aumentando significativamente el tamaño de la ROM.
Los ejecutables basados en RAM funcionan de manera similar, aunque, por supuesto, no tienen una verdadera ROM.
Además, es probable que memset sea un ensamblador en línea muy eficiente, lo que significa que la copia de inicio se puede ejecutar más rápido.
El .bss
segmento es una optimización. Todo el .bss
El segmento se describe con un solo número, probablemente de 4 u 8 bytes, que indica su tamaño en el proceso en ejecución, mientras que el .data
sección es tan grande como la suma de los tamaños de las variables inicializadas. Así, el .bss
hace que los ejecutables sean más pequeños y rápidos de cargar. De lo contrario, las variables podrían estar en el .data
segmento con inicialización explícita a ceros; el programa estaría en apuros para notar la diferencia. (En detalle, la dirección de los objetos en .bss
probablemente sería diferente de la dirección si estuviera en el .data
segmento.)
En el primer programa, a
estaría en el .data
segmento y b
estaría en el .bss
segmento del ejecutable. Una vez que se carga el programa, la distinción se vuelve irrelevante. En tiempo de ejecución, b
ocupa 20 * sizeof(int)
bytes.
En el segundo programa, var
se le asigna espacio y la asignación en main()
modifica ese espacio. Sucede que el espacio para var
fue descrito en el .bss
segmento en lugar del .data
segmento, pero eso no afecta la forma en que se comporta el programa cuando se ejecuta.