undefinierter Verweis auf "nur einige math.h" -Funktionen

8

Ich habe ein seltsames Problem.

Die Math-Bibliotheken wurden meinem Makefile hinzugefügt.

%Vor%

und in der Ausgabedatei (.map) kann ich sehen, dass alles richtig verlinkt ist:

%Vor%

wenn ich das tue

%Vor%

es funktioniert gut. Aber wenn ich eine andere Funktion teste wie:

%Vor%

Ich werde bekommen:

%Vor%

Wie kann das sein? Sowohl pow als auch asin sind in math.h verfügbar, siehe unten:

%Vor%

wie kann man arbeiten und das andere Linker-Problem erzeugen? Wenn ich -nm auf libm.a führe, bekomme ich folgendes Ergebnis: (Entschuldigung für die große Ausgabe, ich habe nur die Abschnitte mit dem Wort kopiert sin )

%Vor%

EDIT1: Ich testete etwas mehr und das Problem ist wie folgt (nicht das, was ich ursprünglich oben angegeben habe):

%Vor%

Was passiert, wenn ich versuche zu bauen, ist, dass ich eine undefinierte Referenz 'in der letzten Zeile bekomme, was bedeutet, dass wenn ich Konstanten verwende, es gut ist, wenn ich Variablen an die sin Funktionen übergebe Es wird nicht verlinkt. Ich habe auch viele der anderen mathematischen Funktionen getestet und bekomme genau das gleiche Linker-Problem. Sobald ich eine Variable an eine mathematische Funktion übergeben habe, kann ich keine Verknüpfung mehr herstellen. irgendwelche Ideen?

    
theAlse 30.06.2011, 11:44
quelle

4 Antworten

5

Der Linker klagt nicht über pow((double) 2, (double) 3) , weil der Compiler ihn durch eine Konstante 8.0 ersetzt. Sie sollten sich nicht auf dieses Verhalten verlassen; Stattdessen sollten Sie immer die Option -lm richtig verwenden. (Übrigens, das ist deutlicher als pow(2.0, 3.0) geschrieben.

Betrachten Sie das folgende Programm:

%Vor%

Wenn ich es auf meinem System kompiliere und verlinke, benutze

%Vor%

Ich bekomme:

%Vor%

Beachten Sie, dass es sich über asin beschwert, aber nicht über pow .

Wenn ich den pow -Aufruf zu pow(x, 3.0) ändere, bekomme ich:

%Vor%

Normalerweise, wenn Sie eine Standard-Math-Bibliotheksfunktion aufrufen wollen, müssen Sie #include <math.h> am Anfang der Quelldatei haben (ich nehme an, Sie haben das schon) und müssen Sie die übergeben -lm Option für den Compiler nach der Datei, die sie benötigt. (Der Linker verfolgt Verweise, die noch nicht aufgelöst wurden. Daher muss er die Objektdatei anzeigen, die sich zuerst auf asin bezieht, damit er sie auflösen kann, wenn er die Math-Bibliothek sieht.)

Der Linker beschwert sich nicht über den Aufruf von pow(2.0, 3.0) , weil gcc clever genug ist, um ihn auf eine konstante 8.0 aufzulösen. Die Funktion pow wird in der kompilierten Objektdatei nicht aufgerufen, sodass sie vom Linker nicht aufgelöst werden muss. Wenn ich pow(2.0, 3.0) in pow(x, 3.0) ändere, weiß der Compiler nicht, was das Ergebnis sein wird, also generiert es den Aufruf.

    
Keith Thompson 10.07.2015, 23:10
quelle
7

Fügen Sie <math.h> überall ein?

Beachten Sie, dass den Namen in der Bibliothek das Präfix __ieee754_ vorangestellt ist, aber die Namen, die der Linker nicht finden kann, nicht sind.

Was passiert, wenn Sie diesen Code kompilieren?

%Vor%

Wenn die Datei mathtest.c ist, dann kompilieren Sie mit:

%Vor%

(Da dies nicht kompiliert werden kann, welche Symbole sind in mathtest.o definiert?)

Ich habe der Hauptfrage einen Kommentar hinzugefügt:

  

Auf welcher Plattform sind Sie tätig? Welchen C-Compiler benutzen Sie? Cross-kompilieren Sie? Was ist die Befehlszeile, die zur Verknüpfung ausgeführt wird? (Ich sehe DOS / Windows C: Pfade und PowerPC-Architektur.) Gibt es eine Chance, die Sie für Typ-generische Mathematik verwenden?

Wenn ich die LOAD-Pfade betrachte, sehe ich:

%Vor%

Was kann, glaube ich, vereinfacht werden zu:

%Vor%

Ein Teil dieses Pfades, der mich fasziniert, ist der nof part; könnte das "kein Gleitkomma" sein? Der andere Teil, der mich wirklich fasziniert, ist das Vorhandensein von powerpc mit dem c: Präfix; Es ist eine Cross-Compilation für PowerPC auf einer Windows-Plattform. Es ist wichtig, offen und deutlich über solche Dinge zu sein; Wir brauchen diese Art von Informationen, um Ihnen sinnvoll helfen zu können.

War das die libm.a -Bibliothek, die Sie getestet haben, oder haben Sie mit einer anderen Datei experimentiert?

    
Jonathan Leffler 30.06.2011 14:05
quelle
6

Die Reihenfolge für -lm -lc -lgcc spielt eine sehr wichtige Rolle. Nur diese Sequenz funktioniert für mich.

Diese Befehle gehen zu den Linker-Optionen!

    
ottelo 27.09.2012 15:06
quelle
0

Sie können "filename.c -lm" verwenden, um dieses Problem zu lösen. Und vergessen Sie nicht, Header-Datei math.h

zu verwenden     
Mayank Kashyap 27.09.2016 09:37
quelle

Tags und Links