2010-10-15 33 views
6

ho una libreria statica con il seguente codice:Membro statico fallimento oggetto di inizializzazione

h di file: file di

class Foo 
{ 
public: 
    Foo() 
    { 
     a = 4; 
    } 

    int a; 
}; 


class Bar 
{ 
public: 
    static const Foo foo; 
}; 

cpp:

const Bar::foo = Foo(); 

mio problema è che Bar :: foo non viene inizializzato con a = 4 fino a qualche tempo dopo main(). Prima di allora a = 0. Sto cercando di accedere a Bar :: pippo da una DLL che si collega staticamente alla libreria sopra. E la mia applicazione si collega a quella DLL ma non accede direttamente a Bar :: pippo. Sto usando Visual Studio 2008.

Qualcuno sa cosa potrebbe succedere?

risposta

7

$ 3.6.2/2- "variabili con durata statica stoccaggio (3.7.1) o filo durata di conservazione (3.7.2) deve essere zero inizializzata (8,5) prima di qualsiasi altra inizializzazione prende posto."

che spiega il motivo per cui si ottiene il valore di 0

$ 3.6.2/4- "E ' implementazione definita se il di inizializzazione dinamica di un variabile non locale con archiviazione statica la durata viene eseguita prima della prima riga . Se l'inizializzazione è posticipata a un certo punto nel tempo dopo la prima istruzione di main, si verifica bef o il primo utilizzo di qualsiasi funzione o variabile definita nella stessa unità di traduzione della variabile da inizializzare. "

Quindi, ciò che si sta cercando di fare porta a un comportamento indefinito, come si sta tentando di accedere a una variabile con una durata di stoccaggio statico, che non è ancora stato inizializzato come nessun codice in quella unità di traduzione è stato utilizzato finora.

+0

comportamento definito dall'implementazione di Microsoft per lo scenario descritto è che l'inizializzazione si sia verificata prima che venga effettuata la chiamata 'process attach' di DllMain(). –

+0

@ Michael Burr: Oh Ok. Questa è una buona informazione. Grazie. – Chubsdad

1

Dove e quando esattamente sta accedendo Bar::foo? Se è un collegamento statico nella DLL, allora dovrebbe essere inizializzato prima del processo di DllMain() 's 'attaccare' viene chiamato.

stai impostando un diverso punto di ingresso per la DLL rispetto al valore predefinito di _DllMainCRTStartup?

+0

Non sto usando _DllMainCRTStartup; la DLL non ha un punto di ingresso di per sé, è solo un mucchio di interfacce di classe astratte e implementazioni con una funzione C esterna extern per creare l'istanza della classe radice. È fatto in questo modo per essere compatibile con i binari. Devo definire un punto di ingresso? – Matthew

+0

'_DlMainCRTStartup' fa parte della libreria di runtime - lo ottieni per impostazione predefinita a meno che tu non faccia qualcosa specificamente per sovrascriverlo. –

+0

@Matthew: come è il codice nell'esecuzione della DLL prima di 'main()'? Ci deve essere qualcosa in 'DllMain()', un punto di ingresso DLL alternativo, o qualche init statico nel tuo .exe deve essere chiamato nella DLL. –

1

Perché non si definisce un metodo statico in bar che restituisce un riferimento a Foo e, in tale metodo statico, ha un'istanza statica di Foo, in modo tale che quando viene chiamato per la prima volta (indipendentemente da dove), otterrà inizializzato correttamente?

class Bar 
{ 
    public: 
    static Foo& foo() 
    { 
     static Foo inst; 
     return inst; 
    } 
}; 
1

Quale codice rileva che Bar::foo non è stato ancora inizializzato?Se si tratta di un altro po 'di inizializzazione statico nella DLL allora probabilmente stai in esecuzione in statica problema ordine di inizializzazione C++ s':

Problemi correlati