Undefinierter Verweis auf `sin`

Ich habe den folgenden Code (auf die Grundlagen für diese Frage reduziert):

#include #include double f1(double x) { double res = sin(x); return 0; } /* The main function */ int main(void) { return 0; } 

Wenn ich es mit gcc test.c kompiliere, gcc test.c ich den folgenden Fehler, und ich kann nicht herausfinden warum:

 /tmp/ccOF5bis.o: In function `f1': test2.c:(.text+0x13): undefined reference to `sin' collect2: ld returned 1 exit status 

Allerdings habe ich verschiedene Testprogramme geschrieben, die sin aus der main aufrufen, und diese funktionieren perfekt. Ich muss hier offensichtlich etwas falsch machen – aber was ist es?

Sie haben Ihren Code mit Verweisen auf die richtige math.h-Headerdatei kompiliert. Wenn Sie jedoch versucht haben, ihn zu verknüpfen, haben Sie die Option zum Einbeziehen der Math-Bibliothek vergessen. Daher können Sie Ihre O-Objektdateien kompilieren, aber Ihre ausführbare Datei nicht erstellen.

Wie Paul bereits erwähnt hat, fügen Sie ” -lm ” hinzu, um mit der Math-Bibliothek in dem Schritt zu verknüpfen, in dem Sie versuchen, Ihre ausführbare Datei zu erzeugen.

In dem Kommentar fragt linuxD :

Warum für sin() in

brauchen wir -lm Option -lm ; aber nicht für printf() in ?

Weil diese beiden functionen als Teil der “Single UNIX Specification” implementiert sind. Diese Geschichte dieses Standards ist interessant und ist unter vielen Namen bekannt (IEEE Std 1003.1, X / Open Portability Guide, POSIX, Spec 1170).

Dieser Standard unterscheidet speziell die Routinen “Standard-C-Bibliothek” von den Routinen “Standard-C-mathematische Bibliothek” (Seite 277) . Die relevante Passage ist unten kopiert:

Standard-C-Bibliothek

Die Standard-C-Bibliothek wird automatisch nach cc durchsucht, um externe Referenzen aufzulösen. Diese Bibliothek unterstützt alle Schnittstellen des Basissystems, wie in Volume 1 definiert, mit Ausnahme der Mathematikroutinen.

Standard C Mathematische Bibliothek

Diese Bibliothek unterstützt die mathematischen Routinen des -lm , wie in Band 1 definiert. Die cc Option -lm wird verwendet, um diese Bibliothek zu durchsuchen.

Die Gründe für diese Trennung wurden von einer Reihe von Faktoren beeinflusst:

  1. Die UNIX-Kriege führten zu einer zunehmenden Abweichung von dem ursprünglichen AT & T-UNIX-Angebot.
  2. Die Anzahl der UNIX-Plattformen fügte Schwierigkeiten bei der Entwicklung von Software für das Betriebssystem hinzu.
  3. Ein Versuch, den kleinsten gemeinsamen Nenner für Softwareentwickler zu definieren, wurde 1988 mit dem Namen POSIX gestartet.
  4. Software-Entwickler, die gegen den POSIX-Standard programmiert haben, stellen ihre Software auf “POSIX-konformen Systemen” zur Verfügung, um mehr Plattformen zu erreichen.
  5. UNIX-Kunden verlangten “POSIX-konforme” UNIX-Systeme zum Ausführen der Software.

Der Druck, der in die Entscheidung zur -lm in eine andere Bibliothek -lm beinhaltete wahrscheinlich, ist aber nicht beschränkt auf:

  1. Es scheint eine gute Möglichkeit zu sein, die Größe von libc niedrig zu halten, da viele Anwendungen keine in der Math-Bibliothek eingebetteten functionen verwenden.
  2. Es bietet Flexibilität bei der Implementierung von mathematischen Bibliotheken, wobei einige mathematische Bibliotheken auf größere eingebettete Nachschlagetabellen angewiesen sind, während andere auf kleineren Nachschlagetabellen (Computerlösungen) zurückgreifen können.
  3. Für wirklich größenbeschränkte Anwendungen erlaubt es die Nicht-Standard-Implementierung der Math-Bibliothek (z. B. das Herausziehen von nur sin() und das Einfügen in eine benutzerdefinierte Bibliothek).

In jedem Fall ist es jetzt Teil des Standards, nicht automatisch als Teil der C-Sprache aufgenommen zu werden. Deshalb müssen Sie -lm hinzufügen.

Ich habe das Problem eh mit -lm hinzugefügt

 gcc -Wall -lm mtest.c -o mtest.o mtest.c: In function 'f1': mtest.c:6:12: warning: unused variable 'res' [-Wunused-variable] /tmp/cc925Nmf.o: In function `f1': mtest.c:(.text+0x19): undefined reference to `sin' collect2: ld returned 1 exit status 

Ich habe kürzlich entdeckt, dass es nicht funktioniert, wenn Sie zuerst -lm angeben. Die Reihenfolge ist wichtig:

 gcc mtest.c -o mtest.o -lm 

Einfach verlinken ohne Probleme

Sie müssen die Bibliotheken danach angeben.

Sie müssen mit der Mathebibliothek, libm, verlinken:

 $ gcc -Wall foo.c -o foo -lm 

Ich hatte das gleiche Problem, das wegging, nachdem ich meine Bibliothek zuletzt aufgelistet hatte: gcc prog.c -lm