2015-10-14 23 views
10

Questa è una domanda molto semplice:variabile globale 0-inizializzato

Does 0-inizializzazione delle variabili globali e statiche hanno alcuna penalizzazione delle prestazioni (anche se molto piccola) in fase di esecuzione?

+1

Normalmente le variabili con durata di archiviazione statica vengono inserite nel blocco '.DATA' del file eseguibile e vengono azzerate al momento della generazione del codice. Quindi la risposta è "No" al meglio delle mie conoscenze. In realtà, ritengo che storicamente questo sia il motivo per cui le variabili con durata di archiviazione statica sono inizializzate a zero, perché non ha alcuna penalità. – Rostislav

+0

@Rostislav Significa che il loader esegue qualcosa come 'memcpy (loading_address, address_of_data_section_with_zeroes, size_of_data_section)'? – Dean

+0

@Rostislav, in generale, non si è corretti, poiché manca un punto molto importante: inizializzazione di default di non pod. – SergeyA

risposta

11

No, poiché lo standard C++ (e C) dice che tutte le variabili globali/statiche non inizializzate in modo esplicito dal programmatore, devono essere inizializzate a zero. Tali variabili sono collocate in un segmento speciale chiamato .bss. Vengono inizializzati a zero prima che venga chiamato main().

Se si inizializza in modo esplicito globale/statico, ma sul valore 0, il compilatore è abbastanza intelligente da renderlo disponibile e lo inserisce ancora nel segmento bss.


È possibile verificare questo per te stesso con un esempio come questo:

#include <stdio.h> 

static int uninit; 
static int init_zero=0; 
static int init_one=1; 

int main (void) 
{ 
    printf("%p\n", &uninit); 
    printf("%p\n", &init_zero); 
    printf("%p\n", &init_one); 

    return 0; 
} 

In questo esempio, le variabili uninit e init_zero finiranno in indirizzi di memoria adiacenti (probabilmente 4 byte distanti), poiché si trovano entrambi nel segmento .bss. Ma la variabile init_one finirà da qualche altra parte interamente, perché è allocata nel segmento .data.

+2

Lo standard dice che devono essere inizializzati a zero, ma dubito che ci sia qualcosa nel segmento '.bss'. Quindi, potrebbe esserci un'architettura in cui l'inizializzazione zero viene eseguita in fase di esecuzione? È corretto? – Rostislav

+0

@Rostislav Anche se lo standard non lo menziona, '.bss' è tradizionalmente il nome di quel segmento su quasi tutte le piattaforme là fuori, dai microcontrollori a 8 bit al PC a 64 bit. In pratica, praticamente ogni applicazione fa questo in fase di esecuzione.Anche su un sistema basato su RAM come un PC, c'è sempre un codice diverso eseguito prima dell'avvio del programma. Su un sistema basato su ROM come un microcontrollore, il programma non ha altra scelta che eseguire il cosiddetto "zero-out" in fase di esecuzione. – Lundin

+0

[Questa risposta] (http://stackoverflow.com/questions/9535250/why-is-the-bss-segment-required/9535579#9535579) fornisce un esempio. – Lundin

-2

Estendendo la domanda dall'inizializzazione 0 (che è solo un sottoinsieme di) all'inizializzazione predefinita, possiamo ancora concludere che di solito non ha alcun impatto misurabile sulle prestazioni dell'applicazione. Tuttavia, è facile progettare una classe che eseguirà, ad esempio, la ricerca nel database nel suo costruttore, portando così a effetti interessanti che si notano durante l'avvio dell'applicazione.