2016-05-06 20 views
10

Ho due file 37064544_p1.cpp & 37064544_p2.cpp con lo stesso contenuto come illustrato di seguito:Come vengono risolti i simboli esterni?

int add(int x,int y) 
{ 
return x+y; 
} 

li ho compilato utilizzando

g++ -c 37064544_p2.cpp -o 37064544_p2.o 
g++ -c 37064544_p2.cpp -o 37064544_p2.o 

e li ha aggiunto a un archivio utilizzando

ar -rsc lib37064544pf.a 37064544_p1.o 37064544_p2.o 

E

$ nm -s lib37064544pf.a 

mi da:

Archive index: 
_Z3addii in 37064544_p1.o 
_Z3addii in 37064544_p2.o 

37064544_p1.o: 
0000000000000000 T _Z3addii 

37064544_p2.o: 
0000000000000000 T _Z3addii 

e

$ ar -t lib37064544pf.a 

mi dà

37064544_p1.o 
37064544_p2.o 

ho un autista, che chiama la funzione _Z3addii che viene compilato con

g++ -static 37064544driver.cpp -o 37064544driver.elf -L. -l37064544pf 

risultato è

Sum : 11 

Domande

  1. Come è il simbolo _Z3addii risolti?

    • Secondo l'indice di archivio?
    • È in base all'ordine in cui popoliamo l'archivio utilizzando ar?
  2. Come posso modificare questo ordine?

  3. Come impedire a ar di avere simboli duplicati?

Compiler: g ++ 4.6.3

+1

Hmm, ho appena provato questo su clang. Se si compila direttamente con i due file .o si ottiene un errore di simbolo duplicato, ma se si inseriscono i due file .o in un file .a e si compila contro di essi, non si verifica alcun errore. Ho sempre pensato che un .a fosse solo un modo conveniente per avere un sacco di file .o, ma sembra che sia diverso in qualche modo. – xaxxon

+1

Il flag "r" su ar sembra che significhi che le cose aggiunte all'archivio in seguito sostituiranno quelle precedenti, sebbene eseguendo con q invece, non riesco ancora a ottenere un errore di simbolo duplicato. Il linker smette di guardare un singolo file quando trova la prima voce per un simbolo che sta cercando forse? – xaxxon

+0

@xaxxon: 'Se si compila direttamente con i due file .o si ottiene un errore di simbolo duplicato,'. Sì, ma non sono sempre a favore di questo per convenienza – sjsam

risposta

2

Come è il simbolo _Z3addii risolto?

L'implementazione è libera di fare ciò che vuole, si sta violando lo one definition rule.

Realisticamente smetterà di cercare un dato simbolo dopo la prima corrispondenza, che presumibilmente segue l'ordine in cui i file sono stati inseriti nell'archivio.

Come posso modificare questo ordine?

Con ar è possibile utilizzare il a (dopo) b (prima) e modificatori di posizionare file oggetto nell'archivio durante l'inserimento di loro, si sta ancora violando l'ODR però.

Come è possibile evitare che AR abbia simboli duplicati?

Non si può per quanto ne so, ar è relativamente muto e per una buona ragione, come alcuni linguaggi permettono di simboli identici, che è il motivo per cui non si dispone di eventuali errori durante il collegamento con l'archivio (no la diagnostica è richiesta per le violazioni ODR).

Puoi forza ld per leggere l'intero archivio

g++ -static 37064544driver.cpp -o 37064544driver.elf -L. \ 
-Wl,--whole-archive -l37064544pf -Wl,--no-whole-archive 

o si può fare un collegamento parziale, invece di un archivio tradizionale, che vi darà un errore se ci sono dei duplicati

ld -r -o lib37064544pf.a 37064544_p1.o 37064544_p2.o 
+0

Grazie, sono d'accordo sul fatto che io stia violando l'ODR, ma questo è stato fatto apposta per quanto riguarda questo esempio, ma il maggiore interesse è stato comunque nel rilevare questo quando si archiviava il codice oggetto. Grazie per il punto sul collegamento parziale. Vorrei anche considerare di aggiungere gli oggetti a librerie diverse e collegarli nell'ordine che voglio. – sjsam

Problemi correlati