Ich habe den folgenden Code (für diese Frage auf das Nötigste reduziert):
#include<stdio.h>
#include<math.h>
double f1(double x)
{
double res = sin(x);
return 0;
}
/* The main function */
int main(void)
{
return 0;
}
Beim Kompilieren mit gcc test.c Ich erhalte die folgende Fehlermeldung, 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 aufrufen sin aus dem main funktionieren, und diese funktionieren einwandfrei. Ich muss hier offensichtlich etwas falsch machen – aber was ist es?
Ich denke, das könnte ein Duplikat sein
– Junge
15. Februar 2011 um 15:13 Uhr
@peoro, es würde mich nicht überraschen. Dies ist eine sehr häufige “vergessene” Bibliothek.
– Edwin Buck
15. Februar 2011 um 15:36 Uhr
Edwin Buck
Sie haben Ihren Code mit Verweisen auf die richtige math.h-Headerdatei kompiliert, aber als Sie versuchten, ihn zu verknüpfen, haben Sie die Option vergessen, die mathematische Bibliothek einzuschließen. Infolgedessen können Sie Ihre .o-Objektdateien kompilieren, aber nicht Ihre ausführbare Datei erstellen.
Wie Paul bereits erwähnt hat, füge hinzu “-lm“, um mit der mathematischen Bibliothek in dem Schritt zu verknüpfen, in dem Sie versuchen, Ihre ausführbare Datei zu generieren.
Im Kommentar fragt linuxD:
Wozu sin() in <math.h>brauchen wir -lm Option explizit; aber nicht für printf() in <stdio.h>?
Denn diese beiden Funktionen sind als Teil der „Single UNIX Specification“ implementiert. Diese Geschichte dieses Standards ist interessant und unter vielen Namen bekannt (IEEE Std 1003.1, X/Open Portability Guide, POSIX, Spec 1170).
Die Standard-C-Bibliothek wird automatisch durchsucht cc um externe Referenzen aufzulösen. Diese Bibliothek unterstützt alle Schnittstellen des Basissystems, wie in Band 1 definiert, mit Ausnahme der mathematischen Routinen.
Standard-C-Mathematikbibliothek
Diese Bibliothek unterstützt die mathematischen Routinen des Basissystems, wie in Band 1 definiert cc Möglichkeit -lm wird verwendet, um diese Bibliothek zu durchsuchen.
Die Gründe für diese Trennung wurden von einer Reihe von Faktoren beeinflusst:
Das UNIX-Kriege führte zu einer zunehmenden Abweichung vom ursprünglichen AT&T UNIX-Angebot.
Die Anzahl der UNIX-Plattformen erschwerte die Entwicklung von Software für das Betriebssystem zusätzlich.
Ein Versuch, den kleinsten gemeinsamen Nenner für Softwareentwickler zu definieren, wurde gestartet, genannt 1988 POSIX.
Softwareentwickler, die gegen den POSIX-Standard programmiert sind, um ihre Software auf “POSIX-konformen Systemen” bereitzustellen, um mehr Plattformen zu erreichen.
UNIX-Kunden forderten “POSIX-kompatible” UNIX-Systeme zum Ausführen der Software.
Der Druck, der in die Put-Entscheidung einfloss -lm in einer anderen Bibliothek wahrscheinlich enthalten, aber nicht beschränkt auf:
Es scheint eine gute Möglichkeit zu sein, die Größe von libc gering zu halten, da viele Anwendungen keine in die mathematische Bibliothek eingebetteten Funktionen verwenden.
Es bietet Flexibilität bei der Implementierung von mathematischen Bibliotheken, wobei einige mathematische Bibliotheken auf größeren eingebetteten Nachschlagetabellen beruhen, während andere möglicherweise auf kleineren Nachschlagetabellen (Computing-Lösungen) beruhen.
Für wirklich größenbeschränkte Anwendungen erlaubt es Neuimplementierungen der mathematischen Bibliothek auf nicht standardmäßige Weise (wie das Herausziehen von nur sin() und es in eine benutzerdefinierte Bibliothek einfügen.
In jedem Fall gehört es jetzt zum Standard, nicht automatisch als Teil der C-Sprache enthalten zu sein, und deshalb müssen Sie hinzufügen -lm.
warum wir für sin (math.h) die Option -lm explizit brauchen, aber nicht für printf() fn, das in stdio.h definiert ist, bezweifle ich die Linker-Fähigkeiten von GNU. Wie in VCC funktioniert es und auf Mac auch wie Flarn2006 erwähnt.
– linuxD
21. März 2013 um 5:55 Uhr
@KeithThompson Der Antwort wurde viel hinzugefügt, um den Kommentar zu beenden. Genießen.
– Edwin Buck
12. Juli 2017 um 15:11 Uhr
Beachten Sie, dass die Systembibliothek auf einem Mac (mit Mac OS X oder macOS) die mathematischen Funktionen enthält. Es gibt eine Bibliothek, auf die Verweise erfüllt werden können -lm in Builds, aber Sie müssen nicht verwenden -lm um die mathematischen Funktionen verknüpft zu bekommen. Das Hauptproblem, das zur Trennung der Mathematikbibliothek vom Rest führte, war, dass CPUs nicht immer über integrierte Gleitkommazahlen verfügten. Es gab Gleitkomma-Coprozessoren (80387 usw.) und so weiter, also gab es viele Möglichkeiten, die Funktionalität bereitzustellen (unter Verwendung von Software-Gleitkommabibliotheken oder Hardware mit unterschiedlichem Umfang an Unterstützung).
– Jonathan Leffler
26. August 2017 um 19:52 Uhr
Beachten Sie auch, dass die moderne POSIX-Spezifikation für c99 „Erweiterte Beschreibung – Standardbibliotheken“ spezifiziert die Bibliotheken etwas anders – wobei darauf hingewiesen wird, dass der Inhalt von -lm (als eine unter vielen anderen) können verlinkt werden, ohne dass eine ausdrückliche Erwähnung in der Kommandozeile für die Verknüpfung erforderlich ist. Das Zitat in der Antwort stammt aus der 4. Ausgabe von SVID (vom Juli 1995). Sie ist historisch relevant, aber nicht mehr bestimmend.
– Jonathan Leffler
26. August 2017 um 20:12 Uhr
Anyeos
Ich habe immer noch das Problem 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 vor kurzem entdeckt, dass es geht nicht Arbeit, wenn Sie angeben -lm Erste. Die Reihenfolge zählt. Sie müssen angeben -lmletzteso was:
gcc mtest.c -o mtest.o -lm
Das verbindet ohne Probleme.
Daher müssen Sie die Bibliotheken am Ende angeben.
Es ist ein Problem, das gcc seit Ewigkeiten nervt 🙂 Ich dachte, dass fünf Jahre und 2 Hauptversionen es geheilt hätten, stattdessen ist es immer noch da! Lustig 🙂
– Lorenzo Dematte
14. November 2013 um 8:47 Uhr
Ich hatte auch das gleiche Problem, als ich den neuesten gcc 4.9 verklagte
– Santiago
12. September 2015 um 13:04 Uhr
Ich freue mich, Ihnen mitteilen zu können, dass dies mit gcc 5.4 oder gcc 6.2.1 nicht passiert.
– Taschen
12. Januar 2017 um 18:43 Uhr
Linken Sie Bibliotheken immer nach Objektdateien. Das funktioniert immer. Das Binden von Bibliotheken vor Objektdateien funktioniert manchmal und manchmal nicht. (Es gibt gelegentliche Ausnahmen – aber sie werden sehr selten angetroffen, und Sie wissen, wann es relevant ist und was zu tun ist, weil die Handbücher für die Bibliothek, die Sie verwenden, es Ihnen sagen, oder weil Sie das Handbuch geschrieben haben.)
– Jonathan Leffler
26. August 2017 um 20:02 Uhr
Danke für diese Antwort! Dieses Bestellproblem besteht weiterhin mit gcc --version von gcc (Ubuntu 8.4.0-1ubuntu1~18.04) 8.4.0. Das schlägt fehl: gcc -lm -Wall -Wextra -Werror -O3 -std=c17 math_sin_is_undefined.c -o bin/aaber das geht vorbei: gcc -Wall -Wextra -Werror -O3 -std=c17 math_sin_is_undefined.c -o bin/a -lm. Das geht auch: gcc -Wall -Wextra -Werror -O3 -std=c17 math_sin_is_undefined.c -lm -o bin/a.
– Gabriel Staples
14. März um 3:45
Paul R
Sie müssen mit der Mathematikbibliothek libm verknüpfen:
$ gcc -Wall foo.c -o foo -lm
Ich hatte das gleiche Problem, das verschwand, nachdem ich meine Bibliothek zuletzt aufgelistet hatte: gcc prog.c -lm
14225000cookie-checkUndefinierter Bezug auf „Sünde“. [duplicate]yes
Ich denke, das könnte ein Duplikat sein
– Junge
15. Februar 2011 um 15:13 Uhr
@peoro, es würde mich nicht überraschen. Dies ist eine sehr häufige “vergessene” Bibliothek.
– Edwin Buck
15. Februar 2011 um 15:36 Uhr