Warum ist -lm in einigen Fällen nicht notwendig, wenn C-Code kompiliert und verknüpft wird?

8

Ich habe hier eine Beispieldatei:

%Vor%

Wenn ich es mit gcc sample.c -o a kompiliere, funktioniert es gut. Ich kann es mit ./a ausführen und es erzeugt die Ausgabe 2.302585 wie erwartet.

Aber wenn meine Datei so aussieht:

%Vor%

es kompiliert nicht mit gcc sample.c -o a . Stattdessen muss ich gcc sample.c -o a -lm verwenden, damit ich es scheinbar "Mathe verknüpfen" sagen kann ... Das ist, wo ich nicht wirklich folge, warum müsste ich Mathe nicht im ersten Beispiel verknüpfen? Und was genau bedeutet es sogar, "Mathematik verknüpfen" zu müssen? Es ist schon eine Weile her, seit ich mit C-Compilern gearbeitet habe, also vergib mir, wenn das eine schlechte Frage ist.

    
user2466999 21.10.2013, 05:18
quelle

3 Antworten

6

Überprüfen Sie die Disassemblierung, und Sie werden wahrscheinlich feststellen, dass der Compiler den Aufruf von log() out vollständig im ersten Fall optimiert (also gibt es nichts zu verknüpfen), aber nicht in der Sekunde. In diesem speziellen Fall definiert Glibc:

%Vor%

in math.h zum Beispiel, und jede Standardbibliotheksfunktion kann als Makro implementiert werden, so dass sie einige dieser Dinge ohne Funktionsaufruf berechnen kann.

    
Paul Griffiths 21.10.2013, 05:27
quelle
5

Die Funktionen der Mathematikbibliothek dürfen nicht aufgerufen werden, entsprechend GCC-Dokument , einige Inline-Funktionen sind definiert und können unter bestimmten Umständen stattdessen aufgerufen werden.

  

... Die GNU C-Bibliothek bietet Optimierungen für viele der häufig verwendeten mathematischen Funktionen. Wenn GNU CC verwendet wird und der Benutzer den Optimierer aktiviert, werden mehrere neue Inline-Funktionen und Makros definiert. Diese neuen Funktionen und Makros haben die gleichen Namen wie die Bibliotheksfunktionen und werden daher anstelle der letzteren verwendet. Im Fall von Inline-Funktionen entscheidet der Compiler, ob es sinnvoll ist, sie zu verwenden, und diese Entscheidung ist normalerweise korrekt.

     

Dies bedeutet, dass keine Aufrufe der Bibliotheksfunktionen erforderlich sein können und die Geschwindigkeit des generierten Codes erheblich erhöht werden kann. Der Nachteil ist, dass die Codegröße zunimmt und der Anstieg nicht immer vernachlässigbar ist.

    
Yu Hao 21.10.2013 05:59
quelle
2

Aus bestimmten Gründen optimiert gcc log (const) sogar mit -O0. Also gibt es im ersten Fall keinen log () Aufruf. Überprüfen Sie die Baugruppe, um Folgendes zu überprüfen:

  

gcc sample.c -S

clang optimiert zum Beispiel nicht auf O0. Aber bei O2 optimiert gcc den Aufruf in beiden Fällen.

    
DmitryB 21.10.2013 05:38
quelle