Stavo leggendo this great post about memory layout of C programs. Dice che le variabili globali inizializzate di default risiedono nello BSS segment e se si fornisce esplicitamente un valore a una variabile globale allora risiederà nello data segment.Perché i compilatori C e C++ posizionano le variabili globali inizializzate e inizializzate in modo esplicito in segmenti diversi?
Ho testato i seguenti programmi in C e C++ per esaminare questo comportamento.
#include <iostream>
// Both i and s are having static storage duration
int i; // i will be kept in the BSS segment, default initialized variable, default value=0
int s(5); // s will be kept in the data segment, explicitly initialized variable,
int main()
{
std::cout<<&i<<' '<<&s;
}
uscita:
0x488020 0x478004
Così, dalla uscita sembra chiaramente come sia variabile I & s risiede in completamente diversi segmenti. Ma se rimuovo l'inizializzatore (valore iniziale 5 in questo programma) dalla variabile S e poi eseguo il programma, mi dà l'output di sotto.
uscita:
0x488020 0x488024
Così, dalla uscita sembra chiaramente come entrambe le variabili i e s risiede nella stessa (in questo caso BSS) segmento.
Questo comportamento è anche lo stesso in C.
#include <stdio.h>
int i; // i will be kept in the BSS segment, default initialized variable, default value=0
int s=5; // s will be kept in the data segment, explicitly initialized variable,
int main(void)
{
printf("%p %p\n",(void*)&i,(void*)&s);
}
uscita:
004053D0 00403004
Così, ancora una volta si può dire, cercando in uscita (mezzi che esaminano l'indirizzo delle variabili), sia le variabili i e s risiedono in segmenti completamente diversi. Ma ancora una volta se rimuovo l'inizializzatore (valore iniziale 5 in questo programma) dalla variabile S e poi eseguo il programma mi dà l'output di sotto.
uscita:
004053D0 004053D4
Così, dalla uscita sembra chiaramente come entrambe le variabili i e s risiede nella stessa (in questo caso BSS) segmento.
Perché i compilatori C e C++ posizionano le variabili globali inizializzate in modo esplicito e quelle predefinite di default in diversi segmenti? Perché c'è una distinzione su dove risiede la variabile globale tra le variabili inizializzate e quelle inizializzate esplicitamente? Se non sbaglio, gli standard C e C++ non parlano mai dello stack, dell'heap, del segmento dati, del segmento di codice, del segmento BSS e di tutte le cose che sono specifiche dell'implementazione. Quindi, è possibile che un'implementazione C++ memorizzi le variabili inizializzate e inizializzate in modo esplicito negli stessi segmenti invece di tenerle in segmenti diversi?
[.bss] (https://en.wikipedia.org/wiki/.bss): "In genere solo la lunghezza della sezione bss, ma nessun dato, è memorizzata nel file oggetto ... I sistemi operativi possono utilizzare una tecnica chiamata zero-fill-on-demand per implementare in modo efficiente il segmento bss " –
Feel con privilegi ... Una volta dovevo usare un compilatore che posizionava variabili statiche in' .data' se avevano l'inizializzatore '= 0', e in '.bss' se non avevano alcun inizializzatore. E ha anche dovuto usare la stessa base di codice su un altro compilatore (non funzionante) che non inizializzava a zero le variabili statiche senza inizializzatore. –
Quiz: cosa significa BSS? –