2016-07-27 10 views
0

Ich habe versucht, eine Quelldatei zu kompilieren, die <math.h> enthält. Allerdings gelang es mir, eine ausführbare Datei zu erstellen, kein Fehler ohne Verbindung zu libm.a.C libm.a muss beim Kompilieren nicht verknüpft werden

Der Befehl war ich getippt gcc -Wall filename.c -o executablename

Ich war mit den externen Bibliotheken zu verknüpfen gesagt (d/Bibliotheken außer libc.a)

Was ist los?

#include <math.h> 
#include <stdio.h> 

int main(void) 
{ 
    double x = sqrt(2.0); 
    printf ("The sqrt of 2 is: %f\n", x); 
    return 0; 
} 
+1

Welche Plattform? Unter Mac OS X ist das zum Beispiel normal. Wie haben Sie die Funktionen von '' benutzt? Wenn die Werte vom Compiler berechnet werden könnten, dann waren sie wahrscheinlich und die Funktionen müssen nicht in der ausführbaren Datei aufgerufen werden, so dass die Verknüpfung nicht bemerken würde, dass Sie nicht mit der Mathematikbibliothek verbunden sind. –

+0

Fügen Sie Ihrer Befehlszeile ein '-v' hinzu und Sie werden sofort sehen, was vor sich geht. –

+2

Ist das ein Copy-Paste des genauen Codes, den Sie verwenden? Weil 'sqrt()' nur ein Argument benötigt, nicht zwei. –

Antwort

1

Die mathematischen Funktionen, die Sie aufrufen, werden durch integrierte Compilerfunktionen implementiert. Versuchen Sie Folgendes, wenn Sie eine Fehlermeldung sehen möchten:

gcc -fno-builtin -Wall filename.c -o executablename 

Zum Beispiel auf meiner Plattform (Ubuntu 14.04.3 LTS), erhalte ich diese Fehlermeldung:

$ cat x.c 
#include <math.h> 
#include <stdio.h> 

int main(void) 
{ 
    double x = sqrt(2.0); 
    printf ("The sqrt of 2 is: %f\n", x); 
    return 0; 
} 
$ gcc -fno-builtin x.c 
/tmp/ccpjG2Pb.o: In function `main': 
x.c:(.text+0x1c): undefined reference to `sqrt' 
collect2: error: ld returned 1 exit status 
+0

Nein sogar mit den -fno-builtin und -Wall Flags kompiliert es immer noch ohne einen Fehler – hemel

+0

Bitte reduzieren Sie Ihr Programm auf das kürzest mögliche Programm das zeigt immer noch deine Frage. Bitte kopieren Sie das Programm in Ihre Frage. Siehe [mcve] für weitere Informationen. –

+0

Der Code wurde hochgeladen – hemel

0

einige Compiler, wie die aktuelle clang unter OS X (die als gcc maskiert) müssen nicht gesagt werden, um Ihre ausführbare Datei mit der Math-Bibliothek zu verknüpfen. Die clang auf OS X wird Ihre ausführbare Datei mit /usr/lib/libSystem.B.dylib (und nur dies für ein einfaches Programm) verknüpfen Diese Bibliothek verwendet wiederum die Bibliothek /usr/lib/system/libsystem_m.dylib, die die mathematische Bibliothek ist.

+0

Was ist, wenn ich gcc auf Cygwin verwende – hemel

+0

@hemel Überprüfen Sie, welche Bibliotheken mit Ihrer kompilierten ausführbaren Datei verknüpft sind.Auf einem normalen Unix-System würde dies mit "ldd a.out" gemacht werden. Sie könnten 'libm' dort sehen. Es ist niemals _wrong_ mit "-lm" zu verknüpfen, wenn Sie mathematische Funktionen verwenden ... und da dies mit dem Verknüpfen anstatt dem Kompilieren zu tun hat, glaube ich nicht, dass "-Wall" sehr viel in Bezug auf das Reporting tun würde (seit dem befasst sich hauptsächlich mit Code-Problemen, nicht mit der Verknüpfung von Problemen. – Kusalananda

0

Die Funktionen in <math.h> (oder die vorzuziehende <tgmath.h>) gehören ebenso zur C-Bibliothek wie viele andere Funktionen. Es ist plattformabhängig, wenn alle Funktionen in der C-Bibliothek tatsächlich in einer einzigen Bibliothek oder separat in mehreren Blöcken verknüpft sind.

In der Antike war die Größe der Bibliotheken ein Problem für die Verbindungszeit, je größer eine Bibliothek war, desto länger dauerte es, ausführbare Dateien mit vielen nicht aufgelösten Symbolen zu verknüpfen. Diese Zeiten sind lange vorbei, aber die Trennung auf einigen Plattformen in libc.a und libm.a herrscht vor.

Wenn Ihre Plattform -lm zum Verknüpfen nicht benötigt, sollte sie eine Dummy (leere) Version von libm.a haben, nur dass es keinen Fehler gibt, wenn Sie diesen auf Ihrer Link-Befehlszeile haben. Dies ist zum Beispiel der Fall für die musl C-Bibliothek, die zu Alpine Linux gehört.

+0

Ein weiterer historischer Grund für die separate Mathebibliothek war, dass einige Maschinen keinen Hardware-Fließkommawert hatten und daher eine Software-Emulationsbibliothek benötigten, während andere Hardware-Fließkommazahlen hatten und die Emulation nicht benötigten. Dies war einfacher zu verwalten, wenn die beiden Bibliotheken getrennt waren. –

+0

Bedeutet das, dass libc.a Funktionen von libm.a unterstützen kann? – hemel

+0

@hemel Die 'libc' (oder wie auch immer das System es nennt) kann alles enthalten, einschließlich mathematischer, kryptographischer, Netzwerk- und Grafik-Rendering-Routinen, wenn es auf einer bestimmten Plattform sinnvoll ist. – Kusalananda