2011-12-02 16 views
12

Le variabili globali vengono inizializzate in ordine di apparire nel modulo di traduzione e nell'ordine relativo di inizializzazione delle variabili in diversi moduli di traduzione in non specificato (il cosiddetto "fiasco dell'ordine di inizializzazione statica").Gli spazi dei nomi influenzano l'ordine di inizializzazione in C++?

Gli spazi dei nomi hanno alcuna influenza su questo? Per esempio se ho questo codice:

//first.cpp 
int first; 
int second; 

avrà alcuna differenza in ordine di inizializzazione rispetto a questo codice:

//second.cpp 
namespace { 
int first; 
} 
int second; 

ci sono casi in cui mettere un oggetto globale in un namespace colpisce ordine di inizializzazione?

+1

Si noti che lo standard C++ definisce che i nomi globali sono solo quelli che vengono visualizzati nell'ambito globale ([basic.scope.namespace]/3). Quindi per quanto riguarda il C++, in second.cpp 'first' non è globale. Ovviamente per tutti gli scopi pratici da fare con "globals" e in particolare "globals" mutevoli essendo una PITA con cui lavorare, in tutti i linguaggi di programmazione, è un "globale". –

risposta

11

3.6 Altre variabili non locali con durata di memorizzazione statica hanno ordinato l'inizializzazione. Le variabili con inizializzazione ordinata definita all'interno di una singola unità di traduzione devono essere inizializzate nell'ordine delle loro definizioni nell'unità di traduzione.

Gli spazi dei nomi non hanno alcun effetto su questo - non menzionato nella sezione.

Quali effetti ha l'ordine sono diverse unità di traduzione. Se è necessario definire l'ordine su di essi, utilizzare un'estensione come l'attributo GCC constructor.

+0

Piuttosto che usare estensioni per controllare l'ordine, consiglierei di evitare del tutto la dipendenza. –

+0

@ DavidRodríguez-dribeas Ancora meglio, evitare l'accumulo di dati statici. – Pubby

5

Bene, la "Variabili globali sono inizializzate in ordine di apparire nel modulo di traduzione" è definita. Non lascia spazio a qualcos'altro, come gli spazi dei nomi, per influenzare l'ordine.

In realtà, "Le variabili globali sono inizializzate in ordine ..." è una citazione imprecisa dello standard come formalmente errata. La dicitura esatta da C++ standard, ISO/IEC 14882: 2003, 3.6.2 comma 1 è:

oggetti con la durata di stoccaggio statico definito in ambito namespace nella stessa unità di traduzione e dinamicamente inizializzato devono essere inizializzati in ordine in cui la loro definizione appare nell'unità di traduzione.

Quindi, piuttosto che "globale" si dice "con stoccaggio statico", cioè tutte le variabili non locali, siano essi membri del namespace globali o membri della classe e se essi sono dichiarati static o meno.

Inoltre aggiunge "e inizializzato dinamicamente". Le variabili con costruttori banali e inizializzatore costante vengono sempre inizializzate per prime (semplicemente caricando i loro valori dal binario) e tutti gli inizializzatori non costanti vengono valutati e i costruttori non banali vengono eseguiti in tale ordine. Questo è importante, quindi puoi ad esempio creare in modo affidabile una lista concatenata in quei costruttori; se è head è un semplice puntatore, è già inizializzato, quindi puoi tranquillamente lavorare con esso.

+0

+1 per l'enfasi: "le variabili globali sono inizializzate in ordine di apparire nel modulo di traduzione" è definito ". Fine della storia! – Nawaz

+0

La frase "definita", come indicato, analizza le variabili globali.roba negli spazi dei nomi definiti dall'utente non è globale –

+0

@ JohannesSchaub-litb: Sì, sono globali. Mi stai costringendo a guardare la dicitura esatta nella specifica. Ok, ecco che arriva ... (vedi modifica). –

Problemi correlati