2012-01-25 36 views
8

Ho cercato di creare codice che utilizza funzioni matematiche (ad esempio pow).Strano comportamento di gcc e math.h?

math.h è incluso e la bandiera -lm viene utilizzata durante la compilazione.

Quando la compilazione viene chiamato in questo modo (-lm bandiera all'inizio del comando), non è riuscito, dicendo che c'è un riferimento definito per pow:

gcc -lm -O3 main.o clustering.o grassberger.o hash.o list.o mat.o metropolis.o motif_ids.o output.o permutation.o prob.o random.o results.o role.o stubs.o switches.o -o mfinder 
main.o: In function `get_sn_motif_id': 
main.c:(.text+0x28d): undefined reference to `pow' 

E quando la bandiera -lm è messo al fine del comando, funziona!

gcc -O3 main.o clustering.o grassberger.o hash.o list.o mat.o metropolis.o motif_ids.o output.o permutation.o prob.o random.o results.o role.o stubs.o switches.o -o mfinder -lm 

È normale?

+0

Oops. Non ho notato che questa è una vecchia domanda. – AnT

risposta

18

Sì, è normale. Per molti linker, l'ordine in cui si specificano i file oggetto e le librerie è importante.

Per citare "An Introduction to GCC - for the GNU compilers gcc and g++":

Il comportamento tradizionale di linker è di cercare funzioni esterne da sinistra a destra nelle librerie specificate sulla riga di comando. Ciò significa che una libreria contenente la definizione di una funzione dovrebbe apparire dopo qualsiasi file di origine o file oggetto che lo utilizza. Questo include librerie specificate con l'opzione scorciatoia -l, come mostrato nella seguente comando:

$ gcc -Wall calc.c -lm -o calc (correct order)

Questo comportamento è comune, ma non è affatto universale. In caso di dubbi, è meglio consultare il manuale del linker. Per esempio, sul mio sistema Ubuntu man ld afferma che:

-l namespec 
    --library=namespec 

     ... 

     The linker will search an archive only once, at the location where 
     it is specified on the command line. If the archive defines a 
     symbol which was undefined in some object which appeared before the 
     archive on the command line, the linker will include the 
     appropriate file(s) from the archive. However, an undefined symbol 
     in an object appearing later on the command line will not cause the 
     linker to search the archive again. 

In altre parole, questo linker si comporta nel modo descritto nel libro gcc.

+0

Anche se va detto che questo non si applicava alle librerie condivise (almeno con gcc), potevano apparire ovunque sulla riga di comando. Quindi le persone lo hanno fatto.Comunque, recentemente è cambiato, gcc ora applica il flag '--as-needed' al linker su molte piattaforme, quindi l'effetto è lo stesso anche per le librerie condivise. – nos

4

Come accennato in An Introduction to GCC - for the GNU compilers gcc and g++

Il comportamento tradizionale di linker è di cercare funzioni esterne da sinistra a destra nelle librerie specificate sulla riga di comando. Ciò significa che una libreria contenente la definizione di una funzione dovrebbe apparire dopo qualsiasi file di origine o file oggetto che lo utilizza.

Penso che tu stia vedendo lo stesso comportamento.

notare che anche altri Stati,

La maggior parte dei linker moderni cercare tutte le librerie, a prescindere dalla fine, ma è meglio seguire la convenzione di librerie che ordinano da sinistra a destra.