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?
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:
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.
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:
(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?
Sie können "filename.c -lm" verwenden, um dieses Problem zu lösen. Und vergessen Sie nicht, Header-Datei math.h
zu verwenden