2012-01-25 18 views
8

Próbowałem utworzyć kod korzystający z funkcji matematycznych (np. pow).Dziwne zachowanie gcc i math.h?

math.h jest dołączony, a flaga -lm jest używana podczas kompilacji.

Kiedy kompilacja jest nazywana tak (-lm flag na początku komendy), nie udało się, mówiąc, że nie jest niezdefiniowana odniesienia do 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' 

A gdy flaga -lm znajdzie się w koniec comand, działa!

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 

Czy to normalne?

+0

Ups. Nie zauważyłem, że to stare pytanie. – AnT

Odpowiedz

18

Tak, jest to normalne. Dla wielu łączników istotna jest kolejność, w której określa się pliki obiektów i biblioteki.

Cytując "An Introduction to GCC - for the GNU compilers gcc and g++":

Tradycyjny zachowanie łączników jest poszukiwanie zewnętrznych funkcji od lewej do prawej w bibliotekach określonych w wierszu poleceń. Oznacza to, że biblioteka zawierająca definicję funkcji powinna pojawić się po plikach źródłowych lub plikach obiektowych, które jej używają. Obejmuje bibliotek określone z -l opcji krótko cięte, jak pokazano w poniższym poleceniem:

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

Takie zachowanie jest powszechne, ale bynajmniej nie jest powszechne. W razie wątpliwości najlepiej jest zapoznać się z podręcznikiem użytkownika linku. Na przykład w moim systemie Ubuntu man ld stwierdza:

-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. 

Innymi słowy, ten łącznik ma zachowywać się w sposób opisany w książce gcc.

+0

Chociaż należy wspomnieć, że nie miało to zastosowania do bibliotek współdzielonych (przynajmniej z gcc), mogły pojawić się w dowolnym miejscu w wierszu poleceń. Więc ludzie to zrobili.Jednak ostatnio to się zmieniło, gcc stosuje teraz flagę '--as-needed' do linkera na wielu platformach, więc efekt jest taki sam dla bibliotek współdzielonych. – nos

4

Jak wspomniano w An Introduction to GCC - for the GNU compilers gcc and g++

Tradycyjny zachowanie łączników jest poszukiwanie zewnętrznych funkcji od lewej do prawej w bibliotekach określonych w wierszu poleceń. Oznacza to, że biblioteka zawierająca definicję funkcji powinna pojawić się po plikach źródłowych lub plikach obiektowych, które jej używają.

Myślę, że widzisz to samo zachowanie.

pamiętać, że również pozostałe kraje,

Większość nowoczesnych łączniki przeszukać wszystkie biblioteki, niezależnie od celu, ale najlepiej jest zgodnie z konwencją bibliotek zamawianiu od lewej do prawej.