2016-04-28 46 views
6

Diciamo che ho una libreria (A) che implementa il modello singleton (ha una variabile statica nella sua implementazione).Cosa succede alle variabili statiche quando le librerie sono collegate staticamente

(A) la libreria è compilata come libreria statica.

Ora, diciamo che ho nel mio probject:

  • (B), un'altra libreria statica che collega in modo statico con (A).
  • (C), un'altra libreria statica che collega staticamente con (A).
  • (D), un programma di livello superiore che collega con (B) e (C).

Alla fine, il mio singleton è davvero un singleton (e la mia variabile veramente statica)? Sono (B) e (C) se si trova la stessa variabile statica da (A) (è unica)? Oppure il fatto che (A) sia stato collegato staticamente due volte il codice (A) incorporato due volte terminando con la mia variabile statica da (A) che appare due volte nel codice binario finale? Quindi se (B) modifica il valore della variabile statica, (C) non vedrebbe la modifica?

Nota: l'ho sperimentato quando modifica le librerie del progetto da collegare in modo statico anziché dinamico. Mi sto solo chiedendo se ho fatto qualcosa di sbagliato, o se si tratta di un normale comportamento noto.

+5

Una libreria statica è fondamentalmente solo un archivio di file oggetto, che viene collegato al file di output come qualsiasi altro file oggetto. –

+0

(D) dovrebbe essere collegato a (A) anche se richiede simboli da (A). (B) e (C) non contengono codice (A). Sarebbe diverso se (B) e (C) fossero dlls/sos. –

+0

I tuoi primi due passaggi non hanno senso. Le librerie statiche sono raccolte di moduli di codice oggetto; non sono "collegati" ad altre librerie statiche. Sono semplicemente "lì". Quando costruisco (D), non vedo come il solo collegamento (B) e (C) si tradurrà in una produzione finale. Quando si inserisce una lib statica che richiede un'altra lib statica, è responsabilità del puller (il collegamento dell'eseguibile) compilare gli spazi vuoti (in questo caso, anche il collegamento in (A)), che dovrebbe dirvi qualcosa su quanti (A) sono nella tua produzione finale. – WhozCraig

risposta

6

Prima di tutto:

(B) e (C) non contengono dei collegamenti contro (A). Le librerie statiche sono compilate, non collegate. Quando si costruiscono (B) e (C) il compilatore potrebbe aver bisogno di vedere alcune definizioni da (A) ma non confondere questo con il collegamento. Il codice (A) non viene copiato in (B) o (C).

Secondo:

(D) dovrà collegare contro (A), (B) e (C). Ciò significa che ottieni una sola copia del codice (A) in (D).

Dynamic-Link Library/oggetto condiviso:

Questo, naturalmente, sarebbe diverso se (B) e (C) sono stati DLL/sos invece. Le DLL sono collegate e quindi se costruisci (B) e (C) come DLL e li colleghi a (A), allora avresti una copia separata del codice (A) in entrambi (B) e (C).

Are (B) e (C) seing la stessa variabile statica da (A)

questo dipende se la variabile ha external or internal linkage. Il seguente file di intestazione contiene una variabile int statica con collegamento interal. Ciò significa che ogni unità di traduzione che include questo file otterrà la propria copia di myVariable.

//MyHeader.h 
#pragma once 
static int myVariable = 0; 
+0

Grazie Mohamad, ha senso. – jpo38

+0

Sapete come assegnare un collegamento esterno a una variabile membro statica in una lib statica in Msvc? O se non è possibile forzare D ad usare una funzione di A che è già stata inclusa in B o C? –

0

libreria collegata statica e variabili statiche non correlate.

Una variabile statica, non è visibile al di fuori dell'ambito di compilazione corrente (nessun nome di simbolo viene creato nel file .o, quindi nessun altro file .o può trovare tale variabile tramite il nome del simbolo).

Ciò significa che la variabile

static int foo; può esistere in ogni ambito di compilazione e ognuno di essi sarà uniqe

0

La tua variabile statica è davvero statica. Sospetto che anche se (B) i collegamenti (A), (B) non raccolgono la propria copia di (A) - invece contiene informazioni che (A) dovrebbero essere collegate.

È tuttavia possibile compilare stesso codice sorgente con variabile statica in due librerie - per esempio:

test.cpp:

int g_myGlobal = 23; 

e compilarlo in (A) e (B) librerie statiche , ma poi quando si collega l'intera applicazione o la DLL - si otterrà l'errore del linker sulla doppia variabile statica definita.

Se invece dichiara variabile con parola chiave static:

test.cpp:

static int g_myGlobal = 23; 

Poi se stesso codice sorgente è legata da (A) e (B) - sarà compilato e collegato ok, ma come risultato si avrà due istanze di variabili g_myGlobal (che possono essere anche diverso).