2012-04-10 8 views
0

Ich programmiere ein c-Projekt, das die in math.h definierte pow-Funktion verwenden muss. Und als ich versuchte, das Projekt zu machen, gcc gab den folgenden Link Fehler: undefined Bezug auf `pow '.Einige Fragen zum Verknüpfen der Mathematikbibliothek

Ich weiß, dass die -lm-Option in meine Link-Anweisung hinzugefügt werden muss, aber es gibt immer noch einige Fragen, die mich verwirren.

Q1: Wenn ich zwei Konstanten in Pow-Funktion übergeben, ist die Verknüpfung ohne -lm erfolgreich. Warum?

Q2: -lm am Ende oder am Anfang der Link-Anweisung führt zu unterschiedlichen Ergebnissen. gcc -lm $ (OBJS) -o exbin ist falsch, aber gcc $ (OBJS) -o exbin -lm ist korrekt. Warum?

Ich benutze ubuntu 11.10 und gcc 4.4.4.

Danke! Bitte entschuldige meinen Pool Englisch.

+0

Sie benötigen keine speziellen Linker-Optionen, um den Standard math.h. Und "pow" benötigt 2 Argumente, weshalb es Ihnen keine Fehler gibt, wenn Sie es (richtig) benutzen. – Perception

Antwort

0

Ich kann Frage 1 nicht beantworten (das scheint seltsam), aber in Bezug auf Frage 2 der Grund gcc -lm $(OBJS) -o exbin funktioniert nicht, weil Sie die Dinge in der Reihenfolge der Verwendung verknüpfen müssen. Dies wird am besten erklärt Beispiel:

/* File func_a.h */ 
/* Declare func_a */ 
void func_a(); 

/* File func_a.c */ 
#include "func_a.h" 
void func_a() 
{ 
    /* do stuff */ 
} 

/* File func_b.c */ 
#include "func_a.h" 
void func_b() 
{ 
    /* Call func_a */ 
    func_a(); 
} 

richtig func_a und func_b in eine ausführbare Datei zu verknüpfen, müssen Sie sie als verknüpfen, da func_bfunc_a verwendet. Kurz gesagt, Sie möchten Ihre Bibliotheksfunktionen immer zuletzt verlinken.

1

Der Compiler weiß über pow(3, 4) oder was auch immer, und optimiert das Programm durch Berechnung des Ergebnisses zur Kompilierzeit, so dass es die Bibliothek nicht bei Link und Laufzeit benötigt.

Ein Linker fügt nichts aus einer Bibliothek hinzu, es sei denn, es weiß, dass es benötigt wird. Bei statischen Bibliotheken stimmte das genau. Bei freigegebenen Bibliotheken würden einige Versionen der Compiler alle Symbole in allen gemeinsam genutzten Bibliotheken, die gelesen wurden, notieren, auch wenn sie zum Zeitpunkt des Scannens der Bibliothek nicht benötigt wurden. Neuere Versionen verwenden nur gemeinsam genutzte Bibliotheken, wenn mindestens eines der Symbole zum Zeitpunkt des Scannens benötigt wird. Wenn die Bibliothek zuerst kommt, ist das einzige benötigte Symbol main() (deshalb wurde main() als Startpunkt für eine gehostete Umgebung festgelegt), und daher wurde die Mathematikbibliothek ignoriert, da keine Symbole darin enthalten waren.