texto - Si una variable global se inicializa a 0, ¿irá a BSS?
variables estaticas (3)
El compilador es libre de poner dicha variable en bss
así como en los data
. Por ejemplo, GCC tiene una opción especial que controla este comportamiento:
-fno-zero-initialized-in-bss
Si el destino admite una sección de BSS, GCC pone por defecto variables que se inicializan a cero en BSS. Esto puede ahorrar espacio en el código resultante. Esta opción desactiva este comportamiento porque algunos programas se basan explícitamente en las variables que van a la sección de datos. Por ejemplo, para que el ejecutable resultante pueda encontrar el comienzo de esa sección y / o hacer suposiciones basadas en eso.
El valor predeterminado es
-fzero-initialized-in-bss
.
Probé con el siguiente ejemplo (archivo test.c
):
int put_me_somewhere = 0;
int main(int argc, char* argv[]) { return 0; }
Compilación sin opciones (implícitamente -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
Compilación con la -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
Todas las variables globales / estáticas inicializadas irán a la sección de datos inicializados . Todas las variables globales / estáticas no inicializadas irán a la sección de datos no iniciales (BSS). Las variables en BSS obtendrán un valor 0 durante el tiempo de carga del programa.
Si una variable global se inicializa explícitamente a cero ( int myglobal = 0
), ¿dónde se almacenará esa variable?
El comportamiento depende de la implementación de C. Puede terminar en .data o .bss, y para aumentar los cambios que no terminan en .data tomando espacio redundante, es mejor no inicializarlo explícitamente a 0, ya que se configurará en 0 de todos modos si el El objeto es de duración estática.
Es bastante fácil probar un compilador específico:
$ 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
Estamos buscando la ubicación de 0000000000601028
y 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
Parece que ambos valores están almacenados en la sección .bss
en mi sistema: gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4)
.