web-dev-qa-db-de.com

Undefinierter Verweis auf "Sünde"

Ich habe den folgenden Code (auf das Nötigste für diese Frage 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 kann nicht herausfinden, warum:

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

Ich habe jedoch verschiedene Testprogramme geschrieben, die sin aus der main -Funktion aufrufen und die perfekt funktionieren. Ich muss hier offensichtlich etwas falsch machen - aber was ist das?

90
robintw

Sie haben Ihren Code mit Verweisen auf die richtige math.h-Headerdatei kompiliert, aber beim Versuch, ihn zu verknüpfen, haben Sie die Option zum Einschließen der mathematischen Bibliothek vergessen. Infolgedessen können Sie Ihre .o-Objektdateien kompilieren, Ihre ausführbare Datei jedoch nicht erstellen.

Wie Paul bereits erwähnt hat, fügen Sie "-lm" Hinzu, um eine Verknüpfung mit der Mathematikbibliothek in dem Schritt herzustellen, in dem Sie versuchen, Ihre ausführbare Datei zu generieren.

Im Kommentar fragt LinuxD :

Warum brauchen wir für sin() in <math.h> Die Option -lm Explizit; aber nicht für printf() in <stdio.h>?

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

Dieser Standard, trennt speziell die Routinen "Standard C-Bibliothek" von den Routinen "Standard C-Mathematikbibliothek" (Seite 307) . Die dazugehörige Passage ist unten kopiert:

Standard C-Bibliothek

Die Standard C-Bibliothek wird automatisch von cc durchsucht, 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 Mathematische Bibliothek

Diese Bibliothek unterstützt die in Band 1 definierten mathematischen Routinen des Basissystems. Die Option cc-lm Wird zum Durchsuchen dieser Bibliothek verwendet.

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

  1. Die NIX-Kriege führten zu einer zunehmenden Abweichung vom ursprünglichen AT & T UNIX-Angebot.
  2. Die Anzahl der UNIX-Plattformen hat die Entwicklung von Software für das Betriebssystem erschwert.
  3. Ein Versuch, den kleinsten gemeinsamen Nenner für Softwareentwickler zu definieren, wurde gestartet, genannt 1988 POSIX .
  4. Softwareentwickler programmierten nach dem POSIX-Standard, um ihre Software auf "POSIX-kompatiblen Systemen" bereitzustellen, um mehr Plattformen zu erreichen.
  5. UNIX-Kunden forderten zur Ausführung der Software "POSIX-kompatible" UNIX-Systeme.

Der Druck, der zur Entscheidung geführt hat, -lm In eine andere Bibliothek zu stellen, umfasste 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 die Mathematikbibliothek eingebetteten Funktionen verwenden.
  2. Es bietet Flexibilität bei der Implementierung von Mathematikbibliotheken, wobei einige Mathematikbibliotheken auf größere eingebettete Nachschlagetabellen angewiesen sind, während andere möglicherweise auf kleinere Nachschlagetabellen (Computerlösungen) angewiesen sind.
  3. Bei Anwendungen mit eingeschränkten Größen ist eine Neuimplementierung der Mathematikbibliothek in nicht standardmäßiger Weise möglich (z. B. indem Sie nur sin() herausziehen und in eine benutzerdefinierte Bibliothek einfügen).

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

110
Edwin Buck

Ich habe das Problem trotzdem mit -lm aufgenommen

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 festgestellt, dass es nicht funktioniert, wenn Sie zuerst -lm angeben. Die Reihenfolge ist wichtig:

gcc mtest.c -o mtest.o -lm

Einfach ohne Probleme verlinken

Sie müssen also die Bibliotheken danach angeben.

61
Anyeos

Sie müssen sich mit der Mathematikbibliothek libm verbinden:

$ gcc -Wall foo.c -o foo -lm 
38
Paul R

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

10
blackappy