Forum: Compiler & IDEs WINAVR-Bug: zuviel SRAM/Flash bei float


von Peter D. (peda)


Lesenswert?

Damit nicht jemand auch fast verzweifelt, wie ich gerade:

Damit der WINAVR float richtig macht, muß man ja den Schalter "-lm" 
benutzen.

Aber das ist nur halb richtig, es kommt außerdem auf die Stellung zum 
C-File an !!!

Also:
1
avr-gcc ... -lm ... test.c ...
geht nicht.
Nur:
1
avr-gcc ... test.c ... -lm ...
geht.

Das macht immerhin den Unterschied von 264 Byte weniger SRAM und 1210 
Byte weniger Flash aus.


Peter

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Das war schon immer so.  Bibliotheken werden genau dann vearbeitet,
wenn sie in der Position auf der Kommandozeile ,,dran'' sind.  Dann
werden für alle bis dato undefinierten globalen Symbole Module aus
der Bibliothek gezogen und gelinkt.  Falls diese Module neue
undefinierte globale Symbole erzeugt haben, wird der Kreis mit der
aktuellen Bibliothek so lange wiederholt, bis diese nicht mehr zu
einer Auflösung von Symbolen beiträgt.  Danach wird diese Bibliothek
,,vergessen'' (genau wie alle anderen bereits gelinkten Objekte) und
mit dem nächsten Objektmodul oder der nächsten Bibliothek auf der
Kommandozeile fortgefahren.

Deine Angabe von -lm ganz vor auf der Kommandozeile war also völlig
nutzlos: zu diesem Zeitpunkt gab es noch keine undefinierten Symbole,
die der Linker daraus hätte auflösen können.  Damit wurden die
(ziemlich aufgeblähten da automatisch generierten) entsprechenden
Routinen aus der libgcc.a stattdessen benutzt.

Dass die libm.a überhaupt Module enthält, die Namen der libgcc.a
doppeln, ist leider historischer Ballast, dessen Auflösung diversen
,,Papierkriegs'' bedarf (Copyright-Abtretung des entsprechenden Autors
an die FSF, damit die formalrechtlichen Voraussetzungen für eine
Integration in den GCC erfüllt sind), bevor man das rein technische
Problem angehen kann.  Außer dem Rewrite der entsprechenden Funktionen
(den Dmitry ja bereits erledigt hat) wäre noch der Einbau entsprechender
Tests für die Qualitätssicherung in die GCC-Testinfrastruktur zu machen,
und dann muss das Ganze im passenden Format an die GCC-Patch-Mailing-
liste gesandt werden.

von Peter D. (peda)


Lesenswert?

Jörg Wunsch wrote:

> Deine Angabe von -lm ganz vor auf der Kommandozeile war also völlig
> nutzlos:

Nungut, ich wußte ja nicht, welcher Mechanismus hinter dem -lm Schalter 
steckt. Zufällig hatte ich das C-File ganz am Schluß.

Alle anderen Argumente scheinen nicht Reihenfolge abhängig zu sein. 
Selbst der Schalter für die prinft-Library mit float darf vor dem C-File 
stehen.

Ich bin da auch nicht der einzige mit dem Problem.
Einer hatte geschrieben, -lm müßte vor dem -o stehen, ein anderer, es 
müßte zweimal dastehen. Deshalb bin ja auch darauf gekommen, die 
Reihenfolge zu permutieren.


Die Standardbibliothek hat auch funktioniert. Allerdings mußte ich erst 
die UART-Puffer runtersetzen, die zusätzlichen 264 Byte SRAM hatten nen 
Stacküberlauf bewirkt.


Peter

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Peter Dannegger wrote:

> Alle anderen Argumente scheinen nicht Reihenfolge abhängig zu sein.

Alles, was Objektmodule oder Bibliotheken betrifft, ist es, also
alle *.o-Dateien, *.a-Dateien oder -l-Optionen.

> Selbst der Schalter für die prinft-Library mit float darf vor dem C-File
> stehen.

Jein.  Aber der funktioniert ohnehin nur mit einem fiesen Trick:
mittels -uvfprintf wird dem Linker von vornherein ein undefiniertes
Symbol names vfprintf aufs Auge gedrückt, damit muss er es sofort
in der danach benannten Bibliothek suchen.  Dieser Trick ist nötig,
da die Applikation selbst nur in den allerseltensten Fällen die
Funktion vfprintf() (die das Herzstück der printf()-Familie ist)
selbst anfordert.

von Volker (Gast)


Lesenswert?

Peter Dannegger wrote:

>>Damit der WINAVR float richtig macht, muß man ja den Schalter "-lm"
>>benutzen.

Was bedeutet das?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

-l ist die Kommandozeilenoption, die dem Linker mitteilt, mit einer 
bestimmten Library zu linken. Der Dateiname der verwendeten Library 
setzt sich zusammen aus den Buchstaben "lib", den unmittelbar auf -l 
folgenden Zeichen und den Zeichen ".a" (das steht für "archive").

-lm also instruiert den Linker, mit der Library libm.a zu linken.

-lfoo würde den Linker anweisen, mit libfoo.a zu linken.

Von wenigen Ausnahmen abgesehen, sollten die zu verwendenden Libraries 
in der gcc-Kommandozeile nach allen Sourcedateien aufgeführt werden.

von Volker (Gast)


Lesenswert?

Also ich hab da nie explizit eine Lib dazugelinkt, obwohl ich schon
öfter "float" benutzt habe. Ich verwendete immer einen mit "mfile" 
erstellten
make-File zum compilieren und linken.
Was wäre denn nun besser gewessen, wenn ich noch die libm.a mittels -lm 
dazugelinkt hätte?

Danke Volker

von Gerry L. (Gast)


Lesenswert?

Hallo Jörg,

auch wenn Peter (trotzdem mein voller Respekt :) )seine Kommentare auch 
manchmal so rüberkommen, nutzlos finde ich jedenfalls seine Angabe 
nicht.

Ich finde es höchst interessant was ich hier immer wieder neu lernen 
kann.

Der Compiler ist für mich nämlich nur ein Instrument der funktionieren 
sollte da ich diesen nicht selbst erstellt habe. Daher beschäftige ich 
mich auch nicht mit diesem.

Hab schon genug mit meinen Sourcen zu tun. ;)

Gibt es eigentlich ne deutsche Dokumentation über alle gcc Optionen bzw. 
solche Hinweise wie die von Peter?

Gerry

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Volker wrote:

> Ich verwendete immer einen mit "mfile"
> erstellten
> make-File zum compilieren und linken.

Dann ist das -lm auch immer mit dabei.

von Volker (Gast)


Lesenswert?

@Jörg Wunsch

danke für die Auskunft, nun hab ich aber noch eine andere Frage:

Ich habe vor etwa 2 Jahren eine ziehmlich umfangreiche Software mit
"Floats" geschrieben, das ganze mit WinAVR20060421.
Als Make File hatte ich einen für meine Bedürfnisse angepassene Makfile 
aus einer 2003-Version (Demo), und da war kein -lm dabei.
Habe gestern abend mal die Files mit -lm (gleiches WINAVR) compiliert 
und
gelinkt, als Ergebnis war das .bin File fast 2K kleiner als ohne -lm.

Wird das mit der Math Library nur kompakter übersetzt, oder ist sind 
ohne auch Fehler in den Float-Berechnungen zu erwarten?
Mich verunsichert, dass Herr Dannegger von einem "Bug" spricht.

Die Codegröße ist mir ziehmlich egal, hauptsache die Berechnungen 
stimmen.

Volker

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Volker wrote:

> Wird das mit der Math Library nur kompakter übersetzt, oder ist sind
> ohne auch Fehler in den Float-Berechnungen zu erwarten?

Die math library enthält handoptimierte Funktionen für Dinge, die
eigentlich in die libgcc.a gehören (und bei fehlendem -lm auch von
dort genommen werden).  Die Funktionen in der libgcc.a sind nicht
fehlerhaft, aber automatisch generierter Code und dadurch
aufgebläht.

> Mich verunsichert, dass Herr Dannegger von einem "Bug" spricht.

Für Peter ist alles ein ,,Bug'', was nicht seinen Vorstellungen
entspricht.  Letztlich war der ,,Bug'' ja, dass der Linker sequenziell
arbeitet (was er im Unix-Umfeld noch nie anders gemacht hat).  Dass
die libm.a Funktionen mit Namen aus der libgcc.a enthält, ist ein
Geburtsfehler des Systems AVR-GCC/avr-libc, den wir hoffentlich mal
irgendwann überwinden werden.

von Volker (Gast)


Lesenswert?

@Jörg

vielen Dank, nun ists klar.

Volker

von Norgan (Gast)


Lesenswert?

> Der Compiler ist für mich nämlich nur ein Instrument der funktionieren
> sollte da ich diesen nicht selbst erstellt habe. Daher beschäftige ich
> mich auch nicht mit diesem.

Sowas finde ich immer ein bisschen traurig. Man sollte sein Werkzeug 
schon kennen und beherrschen. Oder wurdest du einem Automechaniker 
trauen der nicht weiß mit einem 13er Schlüssel umzugehen und dem ständig 
der Schraubendreher runterfällt?

von Martin Schneider (Gast)


Lesenswert?

Hey, woher kennst du meine Fachwerkstatt??

SCNR
Martin

von Peter D. (peda)


Lesenswert?

Norgan wrote:
> Sowas finde ich immer ein bisschen traurig. Man sollte sein Werkzeug
> schon kennen und beherrschen. Oder wurdest du einem Automechaniker
> trauen der nicht weiß mit einem 13er Schlüssel umzugehen und dem ständig
> der Schraubendreher runterfällt?

Der Vergleich hinkt gewaltig.

Besser:
Der Automechaniker muß das Diagnosegerät für die Boardelektronik 
benutzen können.
Er muß aber nicht wissen, wie es funktioniert.


Peter

von yalu (Gast)


Lesenswert?

> Besser:
> Der Automechaniker muß das Diagnosegerät für die Boardelektronik
> benutzen können.
> Er muß aber nicht wissen, wie es funktioniert.

Sagen wir mal so: Zum "benutzen können" gehört auch, die Schwächen des
Werkzeugs zu kennen. Und um die Schwächen besser verstehen und leichter
akzeptieren zu können, ist es von Vorteil, wenigstens ganz grob zu
wissen, wie das Werkzeug funktioniert.

Ein gutes Beispiel sind die Aliasing-Effekte von (älteren) Digitaloszis.
Jemand, der überhaupt keine Ahnung hat, wie das angelegte Sinussignal
auf den Bildschirm gelangt, wird sich wundern, warum der Sinus mit einer
völlig falschen Frequenz angezeigt wird, einen Fehler in der Zeitbasis
vermuten und das vermeintliche Drecksding sofort in die Reparatur geben.

Bei GCC (oder genauer gesagt beim GNU-Linker) ist es eben von Vorteil zu
wissen, dass er jede übergebene Library der Reihe nach und jeweils nur
einmal abklappert wird, um darin nach bisher unaufgelösten Symbolen zu
suchen. Das bringt Geschwindigkeitsvorteile und macht es für den
Anwender bei mehreren gleichnamigen Funktionen oder Variablen leichter,
zu steuern, welche dieser Funktionen/Variablen tatsächlich gelinkt wird.

Auch Computer-Programme sind eben nur Menschen ;-)

von Andreas K. (a-k)


Lesenswert?

Diese Arbeitsweise des Linkers dürfte in der Anfangszeit von Unix auf 
einer 64KB PDP11 recht nützlich gewesen sein. Und weil das also immer 
schon so war, ist man schlicht dabei geblieben.

Das hat auch seine Vorteile. Ohne diese sequentielle Arbeitsweise wäre 
es recht schwierig, Funktionen der Standard-Lib durch solche aus einer 
eigenen zu ersetzen (wie das bei float ja geschieht).

von Peter D. (peda)


Lesenswert?

Aber solche Geheimnisse, daß m die Datei libm.a bedeutet, dürften 
nicht mal 0,1% der GCC-Benutzer kennen.

"-lm" sieht daher wie ein ganz normaler Schalter aus, wie eben auch 
"-Os".


Peter

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Peter Dannegger wrote:
> Aber solche Geheimnisse, daß m die Datei libm.a bedeutet, dürften
> nicht mal 0,1% der GCC-Benutzer kennen.

...der AVR-GCC-Benutzer vielleicht.  Das ist aber eine kleine
Minderheit der GCC-Benutzer.

Der eigentliche Algorithmus ist auf einem OS-basierten GCC auch
etwas umfangreicher: dort wird zuerst eine Datei namens lib<name>.so
gesucht und nur wenn diese nicht gefunden wird eine lib<name>.a.
Dadurch bekommen dynamische Bibliotheken Vorrang vor statischen.

Da der AVR keine dynamischen Bibliotheken kennt, gibt's dort nur
letzteres.  Die Angabe von -l<name> ist übrigens (bis auf die
automatische Suche entlang einer Reihe von Verzeichnissen) völlig
identisch zur direkten Angabe von lib<name>.a, d. h. in beiden
Fällen ist der Algorithmus zur Auswahl der Module aus der Bibliothek
der gleiche.

von Stefan E. (sternst)


Lesenswert?

Peter Dannegger wrote:
> Aber solche Geheimnisse, daß m die Datei *libm.a* bedeutet, dürften
> nicht mal 0,1% der GCC-Benutzer kennen.

Das mag vielleicht für das µC-Umfeld gelten (obwohl ich auch dort 0,1% 
für deutlich zu tief gegriffen halte), da dort ja eher selten 
zusätzliche Libs dazugelinkt werden. Im PC-Umfeld ist das eher 
Basiswissen, da dort ja auch alle Nase lang gleich eine ganze Hand voll 
zusätzlicher Libs gebraucht werden.

Der Fall "-lm" ist aber auch etwas gemein, einfach weil der Name der Lib 
so kurz ist. Bei "-lwxwidgets" ist die Verwechslungsgefahr mit einem 
"normalen" Schalter schon kleiner. ;-)

von Andreas K. (a-k)


Lesenswert?

Es gibt in schönster Unix-Tradition auch andere Programme, deren 
Optionen positionsabhängig wirken. Die universelle Wirksamkeit von -Os 
ist nur eine Annahme vor dir. In diesem Sinne wäre es beispielsweise 
möglich, dass -Os nur für die darauf folgenden Quellfiles wirkt - ich 
weiss nicht ob es so ist, aber es würde der Tradition nicht 
widersprechen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Andreas Kaiser wrote:

> Es gibt in schönster Unix-Tradition auch andere Programme, deren
> Optionen positionsabhängig wirken.

Wobei man der Gerechtigkeit halber erwähnen sollte, dass sowas den
mittlerweile allgemein geltenden Regeln für die Benutzung von
Optionen zuwider ist.  Das ist einfach nur historischer Ballast.

von P. S. (Gast)


Lesenswert?

Wer kam eigentlich auf die Idee, "options" oder "arguments" mit Schalter 
zu uebersetzen? Mit solchen sprachlichen Unschaerfen wird das 
Verstaendnis natuerlich nicht besser.

von Andreas K. (a-k)


Lesenswert?

@Jörg: Wie willst du eine Funktionalität wie -C vom "tar" (chdir) denn 
anders realisieren? Positionsunabhängig ginge ein wesentlicher Teil der 
Funktionalität über Bord.

von Andreas K. (a-k)


Lesenswert?

@Peter: Weil Schalter die korrekte Übersetzung von "switch" ist, und die 
Ausdrucksweise "command line switches" ist ziemlich verbreitet. Und ist 
IMHO besser als "options".

"arguments" sind üblicherweise die Kommandozeilenparameter ohne "-" 
vorweg, da ist eine Übersetzung zu Option schlicht falsch.

von P. S. (Gast)


Lesenswert?

Andreas Kaiser wrote:
> @Peter: Weil Schalter die korrekte Übersetzung von "switch" ist, und die
> Ausdrucksweise "command line switches" ist ziemlich verbreitet. Und ist
> IMHO besser als "options".

Nein, switch ist einfach nur falsch. Es sind Argumente, Parameter, 
Optionen - aber nur in Spezialfaellen Schalter. Und ich wuesste jetzt 
spontan keine halbwegs serioese Quelle, wo ich schonmal "command line 
switches" gelesen haette. In man-pages steht z.B. immer "options", auch 
wenn einige options gar nicht optional sind ;-)

> Und "arguments" sind üblicherweise die Kommandozeilenparameter ohne "-"
> vorweg, da ist eine Übersetzung zu Option schlicht falsch.

Schon die "uebliche" Deklaration von main mit argc und argv legt 
"arguments" als allgemeinen Begriff ziemlich nahe.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Andreas Kaiser wrote:

> @Jörg: Wie willst du eine Funktionalität wie -C vom "tar" (chdir) denn
> anders realisieren?

Die passt in das Posix-Schema nicht rein (und sie ist auch unportabel:
nur GNU-tar macht das so).

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Peter Stegemann wrote:

> Und ich wuesste jetzt
> spontan keine halbwegs serioese Quelle, wo ich schonmal "command line
> switches" gelesen haette.

Gaaanz historisch: RSX-11 hat die Dinger Switches genannt, von da
könnte CP/M sie geerbt haben.

Da MS-DOS ein geklau^H^H^H^H^H^Humgelabeltes CP/M war, könnte der
Begriff von dort in die PC-Welt geraten sein.  Der Schrägstrich
als Trenner und die Tatsache, dass die Switches dem Kommando
nach- statt vorangestellt worden sind, rührt auf jeden Fall noch
davon.

Im Gegensatz dazu hießen die Dinger bein Unix schon immer Options
und kommen normalerweise immer vor den Positionsparametern.

von Andreas K. (a-k)


Lesenswert?

Peter Stegemann wrote:

> Und ich wuesste jetzt spontan keine halbwegs serioese Quelle,
> wo ich schonmal "command line switches" gelesen haette.

Man muss Microsoft nicht unbedingt mögen, aber als halbwegs seriös würde 
ich den Laden schon bezeichnen: 
http://support.microsoft.com/kb/262841/en-us.

Die Wikipedia macht es besonders elegant. Was im Titel "argument" heisst 
wird im Text zu "switch" und im Link zu "option": 
http://en.wikipedia.org/wiki/Command_line_option

von yalu (Gast)


Lesenswert?

Ein paar Beispiele von Linux/Unix-Manual-Pages, in denen die Dinger mit
dem "-" davor als "Switch" bezeichnet werden:

  Xorg a2p as bsdtar cpp emacs free gcc ld mev objcopy objdump strip

Der Begriff "option" ist aber wesentlich häufiger anzutreffen.

In der Manual-Page von gs ist sogar die Rede von "option switches".
Vielleicht sollte man einfach "argument option parameter switches" dazu
sagen, dann macht man's jedem recht :)

von Klaus F. (kfalser)


Lesenswert?

> Gaaanz historisch: RSX-11 hat die Dinger Switches genannt, von da
> könnte CP/M sie geerbt haben.

Noch mehr historisch :
In der Urzeit der Computer hatten die Dinger wirklich Schalter an der 
Vorderseite, mit denen der Programmlauf beeinflusst werden konnte.
Ich meine mich zu erinnern, dass es an der PDP-11 noch 
Betriebssystemkommandos gab, mit denen diese ursprünglichen Schalter 
simuliert, d.h. gesetzt werden konnten.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Klaus Falser wrote:

> In der Urzeit der Computer hatten die Dinger wirklich Schalter an der
> Vorderseite, mit denen der Programmlauf beeinflusst werden konnte.

Man konnte damit die Befehle direkt binär eingeben.  Hat nichts
wirklich mit den Kommandozeilenschaltern gemein. ;-)

von Klaus F. (kfalser)


Lesenswert?

Lang ist's her ...

von Norgan (Gast)


Lesenswert?

Zurück zu den angeblichen 0,1%.  Geheimwissen ist die Linkreihenfolge 
nun wirklich nicht. Das war nicht nur "schon immer so" seit 30 Jahren 
auf Unix, die steht in der GCC Man-Page und auch im langen GCC Manual. 
Manual lesen ist wie Datenblatt lesen: Man sollte es tun.

http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Link-Options.html#Link-Options

Der zweite Absatz bei -l beginnt mit:

> It makes a difference where in the command you write this option; the
> linker searches and processes libraries and object files in the order
> they are specified.

Und der letzte Satz bei -l:

> The only difference between using an -l option and specifying a file name
> is that -l surrounds library with `lib' and `.a' and searches several
> directories.

Ok, da wird etwas geschummelt. Nach shared Libs wird auch gesucht. Für 
den konkreten Fall sind aber alle Infos da:

-lm = libm.a, verarbeitet an der Stelle, an der das -lm in der 
Kommandozeile steht.

Ein Bug ist das schon gar nicht (Bug: Abweichung des Verhaltens von der 
Spezifikation). Im Gegenteil "works as advertised".

von Oliver (Gast)


Lesenswert?

Peter Dannegger wrote:
> Aber solche Geheimnisse, daß m die Datei *libm.a* bedeutet, dürften
> nicht mal 0,1% der GCC-Benutzer kennen.

Spätestens, wenn man mal eine eigene lib bla.a erstellt hat, und sich 
wundert, warum der blöde linker mit -lbla die Datei nicht findet, um 
dann nach einigen Stunden herauszufinden, das die libbla.a heissen muß, 
weiß man das.

Nicht umsonst hat Bill Gates doch ein paar Fans :-)

Oliver

von Volker K. (volker2)


Lesenswert?

>Nicht umsonst hat Bill Gates doch ein paar Fans :-)

Das stimmt wohl - umsonst ist da bei M$ wirklich nix zu haben

von Andreas K. (a-k)


Lesenswert?

Volker K. wrote:

> Das stimmt wohl - umsonst ist da bei M$ wirklich nix zu haben

Doch. Wenn MS mal wieder was verpennt hat und gegen kostenplichtige 
Konkurrenz Marktanteil gewinnen will, dann schon. Siehe früher 
Internet-Explorer vs Netscape und derzeit bei der Virtualisierung.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.