Bei dem C-Programm unten habe ich das Problem das mir die Powl-Funktion
fehlt, mit der gcc-Fehlermeldung undefined reference to `__powl_finite'.
Ersetze ich powl durch pow kommt die Fehlermeldung mit pow statt powl.
Ersetze ich aber in der langen Kommentar-Zeile die 2 durch eine 0, ist
der Fehler weg, nur nützt mir das nichts da ich ja etwas berechnen will
und Variablen brauche und auch Werte ungleich Null brauche.
Andere Funktionen sind problemlos, beispielsweise expl(u/10.0).
Was ist denn an dem Programm falsch?
Erwin Meyer schrieb:> Bei dem C-Programm unten habe ich das Problem das mir die Powl-Funktion> fehlt, mit der gcc-Fehlermeldung undefined reference to `__powl_finite'.
Wie sehen denn dein Comnpiler- und Linker-Aufruf aus? Bei mir geht das
ohne Probleme durch Compiler und Linker.
Erwin Meyer schrieb:> Ersetze ich aber in der langen Kommentar-Zeile die 2 durch eine 0, ist> der Fehler weg
Klar. Dan der Wert von u ja immer gleich, und somit kann das Ergebnis
schon vom Compiler ausgerechnet werden.
Yalu X. schrieb:> -lm vergessen?
Nein, ich compiliere mit
gcc -lm -Wall -o tmp tmp.c
Und das Problem mit fehlendem powl habe ich auch bei Programmen, die
sich vor 12 Jahren problemlos compilieren ließen!
Als funktionierenden Workaround nehme ich erstmal
v = expl(u*logl(10.0)/10.0);
aber es darf kein Dauerzustand sein das plötzlich grundlegende
Funktionen weg sind, die vor Jahrzehnten noch da waren und seit mehreren
Jahrzehnten zum C-Standard gehören.
Das Problem habe ich unter Ubuntu 12.04 (64 Bit), aber NICHT unter SuSE
12.3 (32 Bit).
Ich habe das schnell bei mir getestet. Funktioniert 1a. SLES 11 (64
Bit)/gcc 4.3.4
Kann es sein, das auf Deinem System die libm zerschossen ist? Hast Du
auch mal die 64bit Variante versucht?
Grüsse,
R.
Rene H. schrieb:> Was sagt nm auf libm.so? Sind da die angemeckerten Symbole drin?>> Grüsse,> R.
Also vorhanden ist die
/usr/lib/x86_64-linux-gnu/libm.so
als Link letztlich auf die libm-2.15.so und nm meldet dazu "no symbols".
Aber das kann es zumindest allein nicht sein, denn auf einem anderen
Rechner, unter Debian, ist es ebenso obwohl powl dort vorhanden ist.
Erwin Meyer schrieb:> als Link letztlich auf die libm-2.15.so und nm meldet dazu "no symbols".> Aber das kann es zumindest allein nicht sein, denn auf einem anderen> Rechner, unter Debian, ist es ebenso obwohl powl dort vorhanden ist.
Hmmm.... bei mir sieht das so aus:
$:~> nm /lib/libm-2.11.1.so | grep powl
0001afe0 t __cpowl
000160c0 t __ieee754_powl
00018940 t __powl
0001afe0 W cpowl
00018940 W powl
no symbols klingt für mich nicht sehr gut.
Grüsse,
R.
Malte schrieb:> Erwin Meyer schrieb:>> Nein, ich compiliere mit>>>> gcc -lm -Wall -o tmp tmp.c>> Das -lm an das Ende der Zeile setzen.
Unglaublich aber damit geht es, danke!
Aber das ist nur unter Ubuntu nötig; unter Debian geht es mit -lm vorne,
obwohl es beides 64-Bit-PCs mit dem gcc 4.6.3 sind.
Was mich auch noch etwas wundert:
Erwin Meyer schrieb:> undefined reference to `__powl_finite'.
Es soll also nicht die powl-, sondern die abgespeckte
__pow-finite-Funktion eingebunden werden. Das passiert aber
normalerweise nur dann, wenn man gcc mit einer der Optionen
-ffinite-math-only oder -ffast-math aufruft. Beides scheint bei dir
nicht der Fall zu sein:
Erwin Meyer schrieb:> gcc -lm -Wall -o tmp tmp.c
Oder ist bbei dir gcc ein Alias oder ein Skript, das evtl. noch
weitere Optionen übergibt, die in der Befehlszeiche nicht sichtbar sind?
Rene H. schrieb:> $:~> nm /lib/libm-2.11.1.so | grep powl> 0001afe0 t __cpowl> 000160c0 t __ieee754_powl> 00018940 t __powl> 0001afe0 W cpowl> 00018940 W powl>> no symbols klingt für mich nicht sehr gut.
Bei mir muss ich noch -D (für dynamic) angeben. Das Ergebnis sieht dann
so aus (nm 2.23.2):
1
$ nm -D /lib/libm-2.17.so |grep powl
2
0000000000037d20 T __powl_finite
3
000000000003d990 W cpowl
4
000000000003aad0 W powl
Es sind also beide Varianten (powl und __powl_finite) vorhanden.
In deiner libm scheint aber das fragliche __powl_finite tatsächlich zu
fehlen (vielleicht weil deine libm schon etwas älter ist), was aber kein
Problem sein sollte, wenn man ohne -ffast-math kompiliert.
@Erwin:
Poste doch mal die Versionsnummern von gcc, nm und libm. Da scheint es
ja deutliche Unterschiede zwischen den einzelnen Versionen zu geben. Und
probier mal nm -D zum Auflisten der Symbole in libm.so.
Was mich nach wie vor wundert, dass die Sache bei dir mit
> v = expl(u*logl(10.0)/10.0);
funktioniert.
Was passiert eigentlich, wenn du bei diesem Workaround das -lm weglässt?
Wird dann expl oder __expl_finite vermisst?
Erwin Meyer schrieb:> Unglaublich aber damit geht es, danke!> Aber das ist nur unter Ubuntu nötig; unter Debian geht es mit -lm vorne,> obwohl es beides 64-Bit-PCs mit dem gcc 4.6.3 sind.
Das mit -lm vorne hin schreiben ist neumodischer Sch**ssdr*ck. Seit
Anbeginn der Zeit (1.1.1970) schreibt man das hinten hin.
Ein anständiger Unix-Linker arbeitet die Argumente in einem Durchgang in
der Reihenfolge ab in der sie auf der Kommandozeile angegeben werden. Er
sucht nur nach den Symbolen die beim aktuellen Stand des Linkens
benötigt werden. Schreibt man -lm vorne hin, wird die libm zuerst
abgearbeitet, zu einem Zeitpunkt, an dem noch gar keine Symbole benötigt
werden. Daher interessiert den Linker nicht, was in der libm ist.
Steht -lm hinten, hat der Linker schon tmp.o gesehen wenn er zu libm
kommt, und tmp.o verlangt halt nach ein paar Symbolen, die libm
"zufällig" hat.
Irgendwann sind so ein paar neumodische Hippster, die mit dem Konzept
"Reihenfolge wie auf der Kommandozeile" mental völlig überfordert waren
(ja, Latte saufen macht dumm), hingegangen und haben sich irgendwas
zusammengehackt, das die Reihenfolge irgendwie nicht mehr so richtig
gilt. Manchmal. Vielleicht. An Sommertagen. Sehr "lustig", wenn man
statt gegen eine Standardfunktion gegen eine eigene Implementierung mit
gleichem Namen linken will :-(
Yalu X. schrieb:> Oder ist bbei dir gcc ein Alias oder ein Skript, das evtl. noch> weitere Optionen übergibt, die in der Befehlszeiche nicht sichtbar sind?
Nein, which sagt zum gcc /usr/bin/gcc und das ist ein Link auf das
Programm /usr/bin/gcc-4.6.
> Bei mir muss ich noch -D (für dynamic) angeben. Das Ergebnis sieht dann> so aus (nm 2.23.2):> $ nm -D /lib/libm-2.17.so |grep powl> 0000000000037d20 T __powl_finite> 000000000003d990 W cpowl> 000000000003aad0 W powl>> Es sind also beide Varianten (powl und __powl_finite) vorhanden.
Ja, bei mir auch.
> Poste doch mal die Versionsnummern von gcc, nm und libm. Da scheint es> ja deutliche Unterschiede zwischen den einzelnen Versionen zu geben. Und> probier mal nm -D zum Auflisten der Symbole in libm.so.
gcc: 4.6.3
nm: 2.22
libm: 2.15
> Was mich nach wie vor wundert, dass die Sache bei dir mit>>> v = expl(u*logl(10.0)/10.0);>> funktioniert.>> Was passiert eigentlich, wenn du bei diesem Workaround das -lm weglässt?> Wird dann expl oder __expl_finite vermisst?
Ja, klar.
Was mich wunderte ist das meine Shell-Funktion, die ich seit so 10
Jahren zum Compilieren (+strippen) verwende, plötzlich nicht mehr
funktioniert, weil das -lm nicht ganz am Ende der gcc-Optionen steht.
Hinzu kam verwirrenderweise, das es mit speziellen Werte doch noch ging.
Nach dem Umstellen, also -lm ganz nach hinten, geht es wieder.
Erwin Meyer schrieb:>> Was passiert eigentlich, wenn du bei diesem Workaround das -lm weglässt?>> Wird dann expl oder __expl_finite vermisst?>> Ja, klar.
Meine Frage war schlecht formuliert. Ich meinte eigentlich: Welche der
beiden Funktionen wurde als "undefined reference" gemeldet?
Aber nachdem jetzt alles funktioniert, ist das im Prinzip ja auch egal.
Yalu X. schrieb:> Erwin Meyer schrieb:>>> Was passiert eigentlich, wenn du bei diesem Workaround das -lm weglässt?>>> Wird dann expl oder __expl_finite vermisst?>>>> Ja, klar.>> Meine Frage war schlecht formuliert. Ich meinte eigentlich: Welche der> beiden Funktionen wurde als "undefined reference" gemeldet?>> Aber nachdem jetzt alles funktioniert, ist das im Prinzip ja auch egal.
Achso; ohne -lm werden powl bzw. expl als fehlend gemeldet.
Wie oben beschrieben wird mit -lm unter den mittleren Optionen nur powl
bemängelt, mit __powl_finite, und expl geht problemlos; das ist so
gerade auf der Kippe und geht noch halb - zumindest mit expl.