2012-01-04 7 views
20

Tutte le variabili globali/statiche inizializzate andranno a sezione dati inizializzati. Tutte le variabili globali/statiche non inizializzate andranno alla sezione dati non inizializzata (BSS). Le variabili in BSS otterranno un valore 0 durante il tempo di caricamento del programma.Se una variabile globale è inizializzata su 0, passerà a BSS?

Se una variabile globale è inizializzata esplicitamente a zero (int myglobal = 0), dove verrà memorizzata tale variabile?

+4

Che cosa felice ens quando lo provi? Puoi vedere cosa c'è in un file '.o' usando' objdump -x'. –

+0

Ho provato sotto A) .for int globalvar = 0; objdump -x test> 1.txt B) .for ==> int globalvar; objdump -x test> 2.txt E il diff è: - 2 .bss 00000004 00000000 00000000 00000058 2 ** 2 + 2 .bss 00000000 00000000 00000000 00000058 2 ** 2 -00.000.000 g O.bss 00000004 globalvar +00000004 O * COM * 00000004 globalvar –

+0

@LunarMushrooms Post di aggiornamento * ahem * :) –

risposta

26

Il compilatore è libero di inserire tale variabile in bss e data. Ad esempio, GCC ha un controllo di tale comportamento special option:

-fno-zero-initialized-in-bss

Se l'obiettivo supporta una sezione BSS, GCC per default mette le variabili che vengono inizializzate a zero in BSS. Questo può risparmiare spazio nel codice risultante. Questa opzione disattiva il comportamento poiché alcuni programmi si basano esplicitamente su variabili che vanno a nella sezione dati. Ad esempio, in modo che l'eseguibile risultante possa trovare l'inizio di quella sezione e/o fare ipotesi basate su quello.

Il valore predefinito è -fzero-initialized-in-bss.

provato con il seguente esempio (test.c file):

int put_me_somewhere = 0; 

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

compilazione senza opzioni (implicitamente -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 

compilazione con -fno-zero-initialized-in-bss opzione:

$ 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 
+1

reputazione interessante, hai. –

+1

@EknathIyer l'ho rotto :( –

+0

dayummm, peccato, Eldar –

6

E 'abbastanza facile per testare per una specifica compilatore:

$ 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 

Stiamo cercando la posizione di 0000000000601028 e 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 

Sembra che entrambi i valori sono memorizzati nella .bss sezione sul mio sistema: gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4).

1

Il comportamento dipende dall'implementazione C. Può finire in .data o .bss, e per aumentare le modifiche che non finiscono in .data occupando spazio ridondante, è meglio non inizializzarlo esplicitamente a 0, poiché sarà comunque impostato a 0 in ogni caso l'oggetto è di durata statica.

+0

Questa domanda viene contrassegnata con GCC (sebbene la versione/destinazione non sia specificata). –

Problemi correlati