Guten Abend. Ich interessiere mich für die Gründe, aus denen manche Programmierer für Architekturen, die vom Small Device C Compiler (SDCC) unterstützt werden, nichtfreie Compiler (Keil, IAR, Cosmic, Raisonance, etc) einsetzen. Es wäre schön, wenn die Antworten neben den Gründen auch die jeweiligen Architekturen nennen würden.
Lang ist's her, vermute eine 2.x.0-Version: PIC: Libraries waren nicht kompatibel, müssten aufwändig angepasst werden, um mit dem SDCC zusammenzuspielen. (z.B. das USB-Framework für 16F4550 &co) Inzwischen sind die PIC-Targets im SDCC unmaintained, oder?
Εrnst B. schrieb: > Inzwischen sind die PIC-Targets im SDCC unmaintained, oder? Ja. Immerhin sind die von den PIC-Ports verwendeten gputils nun anscheinend wieder maintained, so dass ein zukünftiger Maintainer der PIC-Ports in SDCC eine Sorge weniger hätte.
Gast
#7133403
Zu den Gründen könnte gehören, daß mehr als nur ein Compiler benötigt wird, sondern auch eine Debugunterstützung. PICs beispielsweise kann man mit dem Microchip Studio beglücken, und da funktionieren PicKit, Mplab Snap etc. als Programmier- und Debuginterfaces. Und wenn so eine Entwicklungsumgebung eines Herstellers eh' schon verwendet wird, und nur eine neue Architektur hinzukommt, muss der Nutzer sich nicht umstellen. Microchip Studio (um beim Beispiel zu bleiben) kann eben als Nachfolger des Atmel Studio nicht nur AVRs, sondern auch PICs und Atmel-ARM (SAMDirgendwas) programmieren. Für AVRs steckt da ein avrgcc drin, aber es gibt auch den microchipeigenen XC8 als Compiler (der ohne zusätzliche Lizenz nur eingeschränkt, d.h. ohne Optimierung verwendbar ist). In manchen Entwicklungsszenarien ist eine Zertifizierung nach irgendwelchen Richtlinien erforderlich (MISRA, kann wohl von IAR geboten werden). Es gibt also eine ganze Latte von Gründen-
DerEgon schrieb: > Zu den Gründen könnte gehören, daß mehr als nur ein Compiler benötigt > wird, sondern auch eine Debugunterstützung. PICs beispielsweise kann man > mit dem Microchip Studio beglücken, und da funktionieren PicKit, Mplab > Snap etc. als Programmier- und Debuginterfaces. Genau. Und das nicht nur für PIC16, sondern auch für PIC18, PIC24 und PIC32. Es macht da einfach gar keinen Sinn, etwas anderes als das Microchip-Komplettpaket zu nehmen, weil es einfach Zeit spart und die Arbeitszeit das eigentlich teure ist und nicht die Lizenzen. Ich verdiene damit mein Geld. Es ist mir daher recht egal, ob der Compiler frei gemäß GNU-Richtlinien ist oder nicht, weil die Kosten vom jeweiligen Projekt getragen werden. Ich habe hier auch einen Kollegen, der IAR für MSP430 benutzt, weil den Entscheidern das Risiko, dass bei einem (nicht notwendigen) Wechsel irgendwas beim Kunden nachher nicht mehr funktioniert, zu groß ist. In einem universitären Umfeld wird das sicher anders sein als in einem Unternehmen. fchk
Gast
#7152843
DerEgon schrieb: > In manchen Entwicklungsszenarien ist eine Zertifizierung nach > irgendwelchen Richtlinien erforderlich (MISRA, kann wohl von IAR geboten > werden). Das dürfte in der Industrie ein Hauptgrund sein. Gegenüber den Personalkosten spielen die Lizenzkosten keine ernsthafte Rolle. Ein Compiler bzw. eine Ganze IDE mit "Stempel drauf" und integrierten Checks schon. Wir haben mal für den AVR den gcc Assebmler-Output gegenüber IAR AVR verglichen, und uns dann ganz schnell für den IAR entschieden (okay schon eine Weile her, das war 2012). Entscheidend dürfte für die meisten professionellen Benutzer sein, ob der Compiler/IDE-Hersteller einen "Guten Draht" zum µC-Hersteller/Designer hat, und so möglichst schnell und gut die Fähigkeiten oder Beschränkungen eines µC´s (oder einer Architektur) auszunutzen. Gruß
Gast
#7152937
SDCC: Schon die Dokumentation der Installation ist lückenhaft. Er erfordert viele zu setzende Umgebungsvariable. Die muss man "raten" und den Inhalt auch. Welche Teile des Compilers und der Binuteils wohin gehören ist das nächste Ratespiel. Ich musste vor vielen Jahren MSC5 von Hand installieren, weil der Installer mit der speziellen Grafikkarte nicht konnte. Selbst das ging wesentlich einfacher.
Heizer schrieb: > Gegenüber den Personalkosten spielen die Lizenzkosten keine ernsthafte > Rolle. Nicht unbedingt immer. In meiner Zeit bei Atmel (auch schon eine Weile her) hat mich mal ein Atmel-Mitarbeiter angesprochen, weil ein namhafter Kunde den IAR durch AVR-GCC ablösen wollte. Der Grund: sie wollten gern nightly builds in einer Serverfarm einführen (was man heute als "CI" bezeichnen würde), und für eine solche Nutzung wären ihnen die IAR-Lizenzkosten explodiert. Aber für die von Philipp genannten Targets dürfte sowas eher irrelevant sein. Da ist ein AVR genauso wenig dabei wie ein ARM.
Bei meinem Ex-Chef ging es auch um Verantwortung, also der Lieferant von der Software wird verantwortlich gemacht wenn irgendwas ist. Und dieses irgendwas kann z. B. sein, - wenn nach einem Update irgendwas nicht mehr läuft, - wenn es beim Debuggen hakt und klemmt, dass die kurzfristig eine Lösung erarbeiten (müssen), - oder wenn man Sonderwünsche hat, - ... Jedenfalls gibt es jemanden, den man treten und ggf. Schadensersatzpflichtig machen kann, wenn es nicht rund läuft und bei den engen Terminen es zu Problemen kommt.
K. H. schrieb: > Jedenfalls gibt es jemanden, den man treten und ggf. > Schadensersatzpflichtig machen kann, wenn es nicht rund läuft und bei > den engen Terminen es zu Problemen kommt. Und das hat je funktioniert und war nicht durch irgendwelche AGB eh ausgeschlossen?
Das weiß ich nicht, jedenfalls war das die Begründung von unserem (unfähigen) Gruppenleiter (GL). Ansonsten hätte unsere Fa. schon mehrfach National Instruments (NI) in den Arsch treten müssen, aber ich denke, unser GL hatte dazu keine "Eier in der Hose" und hat das Problem erstmal auf die Kollegen abgewälzt, solange er sich aus Karrieregründen die Finger nicht schmutzig macht. Also, wenn es hakt und klemmt sind die eigenen Mitarbeiter erstmal Schuld und wenn die beweisen können, dass sie nichts dafür können (ja, sie müssen ihre Unschuld beweisen), dann sind sie irgendwie immer noch Schuld. Erst wenn man den unfähigen GL wegen Verzögerungen anzählen könnte, wurde der aktiv und hat jemanden aus unserer Gruppe damit beauftragt, bei Fa. NI nachzuhaken und Druck zu machen. Das gab es als zusätzliche Aufgabe oben drauf, wir hatten ja Zeit genug, eine Woche hat ja bis zu 148 mögliche Arbeitsstunden. Jedenfalls was er Open Source Zeug gegenüber ziemlich voreingenommen, das war bestenfalls Bastelware. Übrigens hatten wir in solchen Sachen die meisten Probleme mit NI.
Gast
#7153430
Philipp Klaus K. schrieb: > die vom Small Device C Compiler (SDCC) unterstützt werden Wir hatten doch hier mal über die fehlende Eclipse Integration gesprochen. FTDI hatte ja einen Versuch gemacht, das Ergebnis war aber nicht optimal, und inzwischen haben die ja aufgegeben: https://www.ftdichip.com/old2020/Products/ICs/FT51.html Silabs hat ja die Vereinbarung mit ARM/Keil für die kostenfreie Nutzung, dennoch gab es einen Versuch mit Eclipse/Simplicity Studio und sdcc, läuft aber bis Stand heute nicht: https://community.silabs.com/s/question/0D51M00007xeGALSA2/add-the-sdcc-compiler-to-simplicity-studio sdcc mag besser sein als Keil, aber wenn man dafür nicht aus Eclipse/Simplicity Studio flashen/debuggen kann, und mit HEX Datei und Bootloader anrücken muss ...
Philipp Klaus K. schrieb: > Es wäre schön, wenn die Antworten neben den Gründen auch die > jeweiligen Architekturen nennen würden. Beide Beispiele beziehen sich auf den Z80. Haben zwar nichts mit den kommerziellen Compilern zu tun, aber vielleicht hilft es ja trotzdem. David Given (https://github.com/davidgiven/cpmish) wechselt von SDCC zu ACK, unter anderem weil SDCC "buggy" ist. Der Code ist zwar wesentlich schlechter, kann dafür aber 8080. FUZIX (https://github.com/EtchedPixels/FUZIX) beschwert sich im Code oft über SDCC-Bugs und entsprechende Workarounds. Allerdings ist Z80 auch ein Primärtarget für das Projekt. Was den kommerziellen Einsatz betrifft, liegen die Gründe eher in den nicht-technischen Bereichen, die bereits genannt wurden. Wir haben zwar nichts mit kleinen Controllern zu tun, aber nutzen Clang, weil unsere Lieferanten das so vorschreiben. Würde da etwas anderes dranstehen, würden wir auch etwas anderes nutzen, egal was es kostet. Da hängen Haftungsfragen und Zertifizierungen dran, und jeder Patch/Workaround in 3rd-party-code müsste von uns bis in die Ewigkeit selbst gepflegt werden, weil "upstream" die vermutlich nicht integrieren würde. Linux hat sich auch so sehr lange geweigert, Clang-Fixes zu integrieren.
S. R. schrieb: > Philipp Klaus K. schrieb: >> Es wäre schön, wenn die Antworten neben den Gründen auch die >> jeweiligen Architekturen nennen würden. > > Beide Beispiele beziehen sich auf den Z80. Haben zwar nichts mit den > kommerziellen Compilern zu tun, aber vielleicht hilft es ja trotzdem. Der z80-Port unterscheidet sich diesbezüglich deutlich von mcs51, sie sind in gewisser Weise Gegenteile: Bei mcs51 gab es in den letzten Jahren nur wenige Änderungen, die meisten davon Bugfixes. Und Bugs werden dort nur sehr selten gefunden. Bei z80 gab es dagegen eine sehr aktive Entwicklung, vor allem um Codegröße und -geschwindigkeit zu verbessern. Das führt dazu, dass im aktuellen Release 4.2.0 für mcs51 nahezu immer fehlerfreier Code generiert wird, der aber nicht sonderlich effizient ist. Für z80 wird dagegen deutlich effizienterer Code generiert; bekanntwerdende Bugs für z80 werden meist zeitnah behoben, aber durch die vielen Änderungen zur Verbesserung der Effizienz entstanden natürlich auch mehr Bugs. Und wenn man, wie bei FUZIX üblich, mit einem hohen Wert für --max-allocs-per-node kompiliert erhält man noch stärker optimierten Code (um den Preis einer höheren Compilerlaufzeit, und dessen, dass man dann SDCC auf eine Weise verwendet, die nicht so ausführlich getestet wurde). Allgemein ist SDCC aber in den letzten 2 Jahrzehnten deutlich zuverlässiger geworden. Insbesondere hat SDCC auch eine großen Teil der Testsuite von GCC übernommen, wodurch nochmal einige Bugs gefunden und behoben wurden.
Vielen dank für die Antworten. Da es inzwischen hier und andernorts einige gab, und nun nur noch sehr langsam weitere eintreffen, möchte ich eine kurze Zusammenfassung geben. Eine Antwort möchte ich hier in voller Länge zitieren, da sie sehr direkt die beiden meistgenannten Gründe enthält: "In my case the customer requested SDCC based project but it failed to compile into the small flash size. Debugging was quite difficult. Using the Simplicity Studio and Keil Compiler pairing made the code small enough to fit into the device and made debugging much easier." Die 3 meistgenannten Gründe gegen SDCC waren: * Mangelnde Effizienz des von SDCC generierten Codes. * Bessere Debugunterstützung und Integration der nichtfreien Toolchain. * Verfügbarkeit bezahlten Supports für nichtfreie Compiler. Meiner Meinung nach ist nun mittelfristig der aussichtsreichste Weg, SDCC konkurrenzfähiger gegenüber nichtfreien Compilern zu machen: 0) Verbesserte maschinenunabhängige Optimierungen 1) Verbesserte maschinenabhängige Optimierungen für mcs51 2) Bessere Debugunterstützung und Integration 3) Finden und Beheben von Bugs. Insgesamt schätze ich den Aufwand auf eine Vollzeitstelle für gut ein Jahr. Aber auch mit weniger lässt sich natürlich einiges erreichen. Punkt 2 Hätte eigentlich bereits im vom BMBF geförderten Projekt SDCC-STD-UX angegangen werden sollen, wurde dann aber zugunsten verbesserter Unterstützung für C2X zurückgestellt.
Jörg W. schrieb: >> Jedenfalls gibt es jemanden, den man treten und ggf. >> Schadensersatzpflichtig machen kann, wenn es nicht rund läuft und bei >> den engen Terminen es zu Problemen kommt. > > Und das hat je funktioniert und war nicht durch irgendwelche AGB eh > ausgeschlossen? Bei automotive ist das normales Business, wenn der Tier 1 zum vertraglich vereinbarten Zeitpunkt nicht liefern kann oder wegen nicht zertifizierter Tool-Chain etwas passiert wirds teuer für ihn. Schneller (d.h. mit garantierten Reaktionszeiten) Support bei Compilerfehlern ist da auch wichtig.
Gast
#7182792
Philipp Klaus K. schrieb: > Meiner Meinung nach ist nun mittelfristig der aussichtsreichste Weg, > SDCC konkurrenzfähiger gegenüber nichtfreien Compilern zu machen: So, nun ist deine Katze aus dem Sack. Hättes es auch gleich sagen können. Man kann das auch kürzer sagen: der SDCC müßte in allen Punkten besser werden, um mitspielen zu können. Ich hatte sowas ähnliches vor Jahren mit dem GCC bei der Lernbetty gemerkt. Im Vergleich zum Keil ist der GCC weitaus hakeliger in der Benutzung, kann weniger, ist stellenweise inkompatibel zum Standard (__irq und keine Pragmas Arm<-->Thumb) ist unverschämt (kürzt Schleifen, die ICH geschrieben habe einfach weg), ist teilweise buggy (Problem .thumb versus .thumbfunc) und machte dennoch einen umfänglicheren und zugleich langsameren Maschinencode. Der einzige Pluspunkt ist der fehlende Preis, was eigentlich nur für private Bastler wichtig ist. Er hat dennoch seine Berechtigung, denn es heißt "besser schlecht gefahren als gut gelaufen". So ähnlich sehe ich das auch beim SDCC. W.S.
Philipp Klaus K. schrieb: > 1) Verbesserte maschinenabhängige Optimierungen für mcs51 Hallo Philipp, manchmal treten aber mit steigenden Versionen auch Regressionen auf, die mir z.B. bei einer zeitkritischen Anwendung auf die Füße gefallen sind, SDCC 3.8 -> SDCC4.0: https://github.com/Ho-Ro/Hantek6022API/issues/12
W.S. schrieb: > So, nun ist deine Katze aus dem Sack. Hättes es auch gleich sagen > können. Das war beim Namen des Threadstarters aber von vornherein klar. > Im Vergleich zum Keil ist der GCC weitaus hakeliger in der > Benutzung, kann weniger, ist stellenweise inkompatibel zum Standard > (__irq und keine Pragmas Arm<-->Thumb) Was haben Implementierungs-Eigenheiten (alles, was mit zwei Unterstrichen beginnt) und Pragmas mit "Standard" zu tun? Wenn du dann noch den IAR ins Spiel bringst, wird der solche Dinge nochmal anders handhaben – ist sein gutes Recht. Dinge wie das Umschalten des Maschinenmodells oder Interrupts sind schlicht und ergreifend eben kein Standard. Ich hätte gern für mein aktuelles Projekt lieber den GCC genommen, aber ich habe Herstellerbibliotheken mit ELF-Modulen, die Keil-proprietäre Details enthalten (wenngleich ich gar nicht denke, dass sie das bräuchten), und bei denen der GNU-Linker es daher als inkompatibel ablehnt, sie zu linken. $$$ ist in dem Fall zwar nicht das Thema (Lizenzen bezahlt $FIRMA), aber den ganzen Keil-uVision-Salat gibt's halt nur für Windows, also muss ich ihn in einer VM laufen lassen, und dort hat er sich wiederum hakelig damit, auf einem Netzwerklaufwerk zu compilieren – er findet dann sämtliche Include-Files nicht. Herstellersupport dafür? Kannste vergessen, "VM is not officially supported" lautet die lapidare Antwort. Ich weiß, ist off-topic hier, denn es war nach SDCC gefragt, aber zeigt, dass es durchaus Kriterien geben kann, warum man einen kommerziellen Compiler eigentlich gar nicht nehmen möchte aber nehmen muss. (Die MCU ist völlig proprietär, und wahrscheinlich darf ich hier nicht einmal schreiben, welche es ist, weil das schon unter NDA fällt.)
> Man kann das auch kürzer sagen: der SDCC müßte in allen Punkten besser > werden, um mitspielen zu können. Nein. Die Antworten haben gezeigt, wo SDCC besser werden müsste. Umgekehrt erkennt man daran aber auch, wo SDCC schon gut genug ist¹. Und sie haben gezeigt, dass es durchaus möglich ist durch technische Verbesserungen an SDCC die Position von SDCC gegenüber den nichtfreien Compilern zu verbessern². ¹ Z.B. Hat sich niemand bezüglich SDCC über Compilerlaufzeit, Ressourcenbedarf des Compilers oder mangelnde Unterstützung von C-Standards beschwert. ² Es gab zwar durchaus einige, die sich aufgrund von Empfehlungen der µC-Hersteller gegen SDCC entschieden, wegen mangelnder Unterstützung von SDCC in Bibliotheken dritter, oder aufgrund mangelnder Zertifizierungen von SDCC, aber das war eine Minderheit.
Philipp Klaus K. schrieb: > Z.B. Hat sich niemand bezüglich SDCC über Compilerlaufzeit, > Ressourcenbedarf des Compilers oder mangelnde Unterstützung > von C-Standards beschwert. Wieder bezogen auf Z80: SDCC ist einfach sehr langsam, aber mangels guter Alternativen muss man damit einfach leben. Da Programme in der 8-Bit-Welt naturgemäß nicht besonders groß sein können, bleiben auch die Compilezeiten erträglich. W.S. schrieb: > Ich hatte sowas ähnliches vor Jahren mit dem GCC bei der Lernbetty > gemerkt. Im Vergleich zum Keil ist der GCC weitaus hakeliger in der > Benutzung, kann weniger, ist stellenweise inkompatibel zum Standard > (__irq und keine Pragmas Arm<-->Thumb) ist unverschämt (kürzt Schleifen, > die ICH geschrieben habe einfach weg), ist teilweise buggy (Problem > .thumb versus .thumbfunc) und machte dennoch einen umfänglicheren und > zugleich langsameren Maschinencode. Vielleicht solltest du dazu schreiben, dass du nicht in C programmierst, sondern nur in einer Sprache, die ungefähr so ähnlich aussieht.
Gast
#7186290
W.S. schrieb: > ist unverschämt (kürzt Schleifen, > die ICH geschrieben habe einfach weg) Das liegt an Deinen bekanntermaßen dürftigen C-Kenntnissen - nicht am Compiler.
Gast
#7186318
Nop schrieb: > Das liegt an Deinen bekanntermaßen dürftigen C-Kenntnissen - nicht am > Compiler. Und du meinst, ein Compiler darf meine Kenntnisse über irgend etwas abfragen und wenn es ihm nicht paßt, mir einfach mein Geschriebenes wegstreichen? Nö, sowas akzeptiere ich nicht. Der Keil macht solche Faxen übrigens nicht. Und der FCC911 übrigens auch nicht. Das ist der für die Fujitsus. Seltsam, gelle? Ich sehe auch dieses Detail anders als du, nämlich daß du und viele andere zu sehr an den GCC gewöhnt sind und nun alles andere für Geisterfahrer halten. So herum. W.S.
Gast
#7186321
W.S. schrieb: > Und du meinst, ein Compiler darf meine Kenntnisse über irgend etwas > abfragen und wenn es ihm nicht paßt, mir einfach mein Geschriebenes > wegstreichen? Ein C-Compiler darf (nicht: muß!) Dinge unter der as-if-Regel streichen, wie das im C-Standard vorgesehen ist. Wenn Du den C-Standard nicht kennst, d.h. Du kannst kein C, ist das Dein Problem und nicht das des Compilers.
Gast
#7186327
Er fragt keine Kenntnisse ab, sonder setzt das Verhalten um, was ihm in der Programmiersprache beschrieben wurde. Da es kein C–Keyword für „Warte mal kurz“ gibt, stellt er fest das die Schleife keine Änderung am Programmzustand hervorruft und genau das übersetzt er dann dann in ein „don‘t execute anything“. Und das so schnell wie irgend möglich. Es gibt in C auch die Möglichkeit zu erklären, das da was passiert, was der Compiler nicht sieht (volatile) und dann respektiert er das. Nur hinschreiben muß es der Programmierer.
S. R. schrieb: > Philipp Klaus K. schrieb: >> Z.B. Hat sich niemand bezüglich SDCC über Compilerlaufzeit, >> Ressourcenbedarf des Compilers oder mangelnde Unterstützung >> von C-Standards beschwert. > > Wieder bezogen auf Z80: SDCC ist einfach sehr langsam, aber mangels > guter Alternativen muss man damit einfach leben. Beim Z80 wären die Alternativen sdcc mit einem kleinen Wert für --max-allocs-per-node, sowie zcc und ack. Die sind alle ebenfalls frei, aber generieren üblicherweise schlechteren Code. Umgekehrt kann man sdcc mit hohem Wert für --max-allocs-per-node oft noch langsamer machen und dafür noch etwas besseren Code erhalten.
Gast
#7186851
Philipp Klaus K. schrieb: > nichtfreie Compiler ... einsetzen. Ist das nicht die gleiche Frage wie Linux/Windows, Libre/MS, Gimp/PS etc? Also Total_Cost_of_Ownership, Killerfeatures, Ausfallrisiko, Integration, Kundenanforderungen, Gewohnheit, Schmiergeld (Seminare etc.), ... nicht unbedingt in der Reihenfolge.
A. S. schrieb: > Ist das nicht die gleiche Frage Nein, sie war deutlich konkreter gestellt, und wenn du dir den Rest des Threads ansiehst, dann vor allem deshalb, weil Philipp offenbar wissen möchte, an welcher Stelle er weitere Manpower am besten ansetzen sollte.
Gast
#7187438
Gcc schrieb: > Er fragt keine Kenntnisse ab, sonder Gcc schrieb: > Er fragt keine Kenntnisse ab, sonder... Das ist mir klar, diese Bemerkung war auch nur zum Zwecke der Vedeutlichung. Um es mal klar zu sagen: von einem Compiler erwarte ich, daß er das, was ich haben will, optimal von der Sprache der Notation in entsprechenden Maschinencode übersetzt, aber NICHT, daß er an meinem Geschriebenen herum mäkelt und nur dann, wenn es im Sinne seiner Programmierer ist, das Zeug übersetzt. Wenn das nicht gegeben ist, dann ist so ein Compiler nicht geeignet für alle Firmware, die in irgend einer Weise mit Hardware zu tun hat. Und ein Standard, der derartige Eigenmächtigkeiten sanktioniert, taugt nur für die Tonne. Aber zurück zum Thema, was man besser "warum nehmen die Leute nicht NUR den SDCC?" hätte nennen können. Der Philipp schrieb: > 0) Verbesserte maschinenunabhängige Optimierungen > 1) Verbesserte maschinenabhängige Optimierungen für mcs51 > 2) Bessere Debugunterstützung und Integration > 3) Finden und Beheben von Bugs. Tja, ist das nicht alles, wenn die Rede ist von einem Compiler? Also, was denn sonst noch - außer Pillepalle? W.S.
Gast
#7187520
W.S. schrieb: > Um es mal klar zu sagen: von einem Compiler erwarte ich, daß er das, was > ich haben will, optimal von der Sprache der Notation in entsprechenden > Maschinencode übersetzt, Soweit, so schön. Das macht annähernd jeder Compiler so, sofern er nicht irgendwas zusammengefrickeles aus dem 1. Semester der Informatik-Vorlesung ist. > aber NICHT, daß er an meinem Geschriebenen herum mäkelt Dann schalte halt alle Warnungen aus, wenn Du zu blöd bist, C programmieren lernen zu wollen. Leb' dann aber auch mit den Ergebnissen, ohne rumzuheulen. > und nur dann, wenn es im Sinne seiner Programmierer ist, > das Zeug übersetzt. Das ist drollig: Ein standardkonformer C-Compiler, der den Code (oder Kot?) des Lernbetty-Großmeisters nicht so übersetzen will, wie es der Herr Großmeister will, wird abgelehnt. Wielange dauert es eigentlich noch, bis Du a) entweder C programmieren lernst oder b) Dich anderen Dingen zuwendest?
W.S. schrieb: > Um es mal klar zu sagen: von einem Compiler erwarte ich, daß er das, was > ich haben will, optimal von der Sprache der Notation in entsprechenden > Maschinencode übersetzt Genau das macht ein Compiler übrigens, wenn er
1 | |
2 | |
zu nichts übersetzt, denn "nichts" ist sowohl von der Laufzeit als auch vom Speicherverbrauch her die optimale Umsetzung einer Schleife, die schlicht nichts macht. Die Zuweisung von Daten zu einer Variablen, die man hinterher nicht wieder abfragt, ist eben halt aus Sicht eines Compilers "nichts".
Gast
#7187866
Jörg W. schrieb: > W.S. schrieb: >> Um es mal klar zu sagen: von einem Compiler erwarte ich, daß er das, was >> ich haben will, optimal von der Sprache der Notation in entsprechenden >> Maschinencode übersetzt > > Genau das macht ein Compiler übrigens, wenn er > 1 for (int i = 0; i < 10000; i++) > 2 { /* nothing */ } > > zu nichts übersetzt, Der Compiler meint, daß es nichts sein soll. Man könnte so etwas als eine Art Verzögerung einsetzen, da jeder Befehl eine bestimmte Anzahl von Taktzyklen benötigt. Ob das am Ende guter Programmierstil ist sei mal dahin gestellt, aber es würde vom Prinzip her funktionieren. Vielleicht könnte der W.S. einfach mal ein Beispiel bringen.
Gast
#7187989
Wer C programmieren kann, wüsste, wozu "volatile" verwendet werden kann. Wer sich hingegen weigert, dem hilft auch keine "Lernbetty".
Zeno schrieb: > Vielleicht könnte der W.S. einfach mal ein Beispiel bringen. Der W.S. könnte auch einfach in C programmieren anstatt in einer Programmiersprache, die nur so aussieht wie C. Das ist nämlich das eigentliche Problem.
Gast
#7188147
S. R. schrieb: > Der W.S. könnte auch einfach in C programmieren anstatt in einer > Programmiersprache, die nur so aussieht wie C. Das ist nämlich das > eigentliche Problem. Wenn Du meinst.
Gast
#7188399
Betty hilft auch hier nicht weiter schrieb: > Wer C programmieren kann, wüsste, wozu "volatile" verwendet werden kann. > > Wer sich hingegen weigert, dem hilft auch keine "Lernbetty". Man muß ja mit W.S. nicht immer einer Meinung sein und in manchen Dingen ist er sicher auch etwas speziell. Dennoch kann man sich ja auch das was er z.B. mit der Lernbetty verbrochen hat ansehen. Ich habe das vor ein paar Jahren mal getan und mir das ganze Betty Geraffel herunter geladen. Es hat so funktioniert wie er es beschrieben hat - völlig problemlos vom Compilieren der Quellen, Übertragen des Compilats auf die Betty und die Funktion selbst. Also für einen der kein C kann nicht ganz schlecht. Die Dokumentation zu seinem Projekt ist auch nicht schlecht gemacht, die Mehrzahl solcher Projektdokumentationen, wenn es denn überhaupt welche gibt, ist deutlich schlechter. Ansonsten stell doch mal selbst ein solches Projekt auf die Beine und beweise wie man es besser macht. Deine 2 Post in diesem Thread sind bisher nur unqualifiziertes Geblöke ohne jegliche Substanz.
Zeno schrieb: > Der Compiler meint, daß es nichts sein soll. Man könnte so etwas als > eine Art Verzögerung einsetzen, da jeder Befehl eine bestimmte Anzahl > von Taktzyklen benötigt. Es gibt aber in C keinen "Befehl", und es gibt auch keine vorgeschriebenen Mindestausführungszeiten. Das würde letztlich der Forderung nach möglichst optimaler Umsetzung des aufgeschriebenen Codes zuwider laufen. GCC hatte früher für diesen Konstrukt tatsächlich eine "Sonderlocke" implementiert, aber das war zusätzlicher Aufwand, just diese Situation ("toter Code, der stehen bleiben soll") zu erkennen, und irgendwann haben sie halt diese Sonderlocke abgeschafft.
Gast
#7188943
Jörg W. schrieb: > Es gibt aber in C keinen "Befehl", und es gibt auch keine > vorgeschriebenen Mindestausführungszeiten. Das würde letztlich der > Forderung nach möglichst optimaler Umsetzung des aufgeschriebenen Codes > zuwider laufen. Ach Jörg, jetzt hör mal mit dieser Erbsenzählerei auf, Du bist intelligent genug um zu wissen worauf ich hinaus wollte. Ob man das nun Befehl, Anweisung oder wie auch immer benennt ist am Ende doch völlig Rille. Schlußendendlich macht der Compiler am Ende daraus eine Folge von Instruktionen für die CPU die entsprechend umgesetzt werden. Für ein i++ sind nun mal eine bestimmte Anzahl von Taktschritten erforderlich um dies umzusetzen, am Ende wird die weitere Befehlsausführung um genau die Zeit die für die Ausführung erforderlich ist verzögert. Es könnte also durchaus sein, das sich der Programmierer was dabei gedacht hat und insofern wäre es schon wünschenswert, wenn der Compiler das umsetzt was man hinschreibt, zumindest solange es sich um erlaubte Codesequenzen handelt. Der Compiler kann ja in solch einem Fall eine Warnung ausgeben und es dem Programmierer überlassen ob er es denn so stehen lassen will.
Zeno schrieb: > Für ein i++ > sind nun mal eine bestimmte Anzahl von Taktschritten erforderlich um > dies umzusetzen, am Ende wird die weitere Befehlsausführung um genau die > Zeit die für die Ausführung erforderlich ist verzögert. Es könnte also > durchaus sein, das sich der Programmierer was dabei gedacht hat und > insofern wäre es schon wünschenswert, wenn der Compiler das umsetzt was > man hinschreibt, zumindest solange es sich um erlaubte Codesequenzen > handelt. Diesen Thread habe ich begonnen, da SDCC-Entwickler nur wenig über jene wissen, die SDCC nicht verwenden. Über die Nutzer von SDCC wissen wir dagegen deutlich mehr, da diese ja über Mailinglisten, Tracker, etc mit uns in Kontakt sind. Nutzer mit obiger Ansicht gibt es durchaus, aber es ist eine kleine, schrumpfende Minderheit. Ja, der Programmierer hat sich etwas gedacht, als er das ++ schrieb. Aber heutzutage ist das ++ (oder was auch immer) oft in einem Makro oder einer inline-Funktion, die dann mit konstanten Parametern aufgerufen werden, die dann dazu führen, dass jenes ++ gar nicht gebraucht wird. Und der Programmierer hat sich gedacht, dass das kein Problem ist, da der Compiler es ja wegoptimieren kann, wenn es nicht gebraucht wird. Nur mal ein Beispiel: An SDCC wird häufig kritisiert, dass es jede Funktion, die in einer Quellcodedatei steht, auch in die Binärdatei kompiliert (wenn man also mehrere .c zu .rel kompiliert und diese dann zusammenlinkt, ohne eine .lib zu verwenden), selbst wenn die betreffende Funktion gar nicht aufgerufen wird. Da geht es also nicht mal um ein einzelnes ++ oder eine leere Schleife, sondern um ganze Funktionen, von denen die Programmierer erwarten, dass der Compiler diese wegoptimiert!
Zeno schrieb: > Es könnte also durchaus sein, das sich der Programmierer was dabei > gedacht hat Wie Philipp schon schreibt: oft genug hat der Programmierer das nicht so direkt hingeschrieben, sondern es versteckt sich innerhalb von irgendwas anderem. Wenn du 'i = i * 2' schreibst, erwartest du ja auch nicht, dass dann der (bei Fehlen von Multiplikationsbefehlen in der CPU in einer Bibliothek sitzende) Code für eine Multiplikation mit 2 ausgeführt wird, wenn der Compiler eigentlich auch feststellen kann, dass er stattdessen viel einfacher nur ein Bit nach links schieben muss. Wenn du zehnmal 'i++' ausführst, ohne dass das Ergebnis verwendet wird, erwartest du auch keine 10mal ausgeführte Schleife, wenn die direkte Addition einer 10 das gleiche tut. So ist es eben auch, wenn du in einer Schleife irgendwas aufaddierst, das am Ende gar nicht benutzt wird. Verzögerungen jeglicher Art, insbesondere solche mit einem irgendwie definierbaren Zeitverhalten, sind daher maschinenabhängig und lassen sich nur entsprechend auf diesem Niveau implementieren. Ob man dafür nun in die Schleife simpel einen "NOP" setzt oder ob es eine gut ausgefeilte Infrastruktur dafür gibt (wie beim AVR-GCC, bei dem der Compiler taktgenaue Verzögerungen nicht nur mit Schleifen sondern auch mit sauber gezählten NOPs machen kann), es führt kein Weg dran vorbei, sich sowas von Fall zu Fall selbst anzusehen statt den Compiler, von dem man erwartet, dass er "optimal von der Sprache der Notation in entsprechenden Maschinencode übersetzt" zu beschuldigen, dass er den Code wegwirft, der aus seiner Sicht schlicht nichts macht.
Zeno schrieb: > Der Compiler kann ja in solch einem Fall eine Warnung ausgeben > und es dem Programmierer überlassen ob er es denn so stehen lassen will. Die Warnung kannst du ja ganz leicht nachrüsten. Einfach im Build-System zweimal kompilieren lassen, einmal mit -O0, einmal mit -Os,-O2,-O3... Dann die ausgeworfen Binaries vergleichen. Falls unterschiedlich: "Warnung: Compiler hat optimiert!"
Gast
#7189273
Zeno schrieb: > Für ein i++ > sind nun mal eine bestimmte Anzahl von Taktschritten erforderlich So funktioniert C ganz grundsätzlich nicht. Deswegen kann man das von einem C-Compiler auch nicht erwarten. > Es könnte also > durchaus sein, das sich der Programmierer was dabei gedacht hat Dann hätte er "volatile" hinschreiben sollen. Wenn er das so wie W.S. nicht weiß, hätte er vorher C lernen sollen. > insofern wäre es schon wünschenswert, wenn der Compiler das umsetzt was > man hinschreibt Nein. Nochmal, so funktioniert C nicht.
Gast
#7189400
Jörg W. schrieb: > Wie Philipp schon schreibt: oft genug hat der Programmierer das nicht so > direkt hingeschrieben, sondern es versteckt sich innerhalb von irgendwas > anderem. Wenn du 'i = i * 2' schreibst, erwartest du ja auch nicht, dass > dann der (bei Fehlen von Multiplikationsbefehlen in der CPU in einer > Bibliothek sitzende) Code für eine Multiplikation mit 2 ausgeführt wird, > wenn der Compiler eigentlich auch feststellen kann, dass er stattdessen > viel einfacher nur ein Bit nach links schieben muss. Jörg ich habe den Eindruck Du willst micht nicht verstehen und Dein Vergleich hinkt auch. Mir ist es völlig wurscht wie der Compiler 'i = i * 2' umsetzt. Ob er dafür eine in der CPU evtl. vorhandene Multiplikationsinstruktion benutzt oder einfach nur ein Bit nach links schiebt ist mir in diesem Zusammenhang völlig egal. Ich erwarte schlichtweg das er den von mir hingeschriebenen Quelltext, solange er gültigen Code darstellt, in ausführbare Instruktionen für die CPU umsetzt, aber nicht entscheidet das der hingeschriebene Code eigentlich, nach seiner Ansicht, überflüssig ist und ihn deswegen einfach weg läßt. Der richtige Weg wäre, daß er mir in so einem Fall mitteilt das ich diese Codesequenz nochmals überdenken solle. Compiler für andere Sprachen handhaben das anders und akzeptieren das was der Programmierer hin schreibt. Ich merke aber schon, das ich hier gegen Windmühlen kämpfe und die Fangemeinde dieses Verhalten toll findet und lieber volatile hinschreibt, um dem Compiler zu sage, mache es so wie ich es hingeschrieben habe. So wird halt jeder auf seine Art glücklich. Mich piept so etwas an und genau deshalb meide ich C wo es nur geht, aber leider führt bei µC oftmals kein Weg daran vorbei. Εrnst B. schrieb: > Die Warnung kannst du ja ganz leicht nachrüsten. > Einfach im Build-System zweimal kompilieren lassen, einmal mit -O0, > einmal mit -Os,-O2,-O3... > Dann die ausgeworfen Binaries vergleichen. Falls unterschiedlich: > "Warnung: Compiler hat optimiert!" Du hast ja nun mal gar nicht verstanden worum es mir geht - macht aber nichts.
Zeno schrieb: > Du hast ja nun mal gar nicht verstanden worum es mir geht Nach deinen zusätzlichen Ausführungen oben: Doch, das habe ich exakt verstanden. Ich hab mich nur darüber Lustig gemacht.
Gast
#7189409
Nop schrieb: > So funktioniert C ganz grundsätzlich nicht. Deswegen kann man das von > einem C-Compiler auch nicht erwarten. > ... Ja und genau deswegen fallen viele Anfänger erst mal so richtig auf die Fresse.
Gast
#7189411
Εrnst B. schrieb: > Ich hab mich nur darüber Lustig gemacht. Also wieder mal die typische Arroganz der eingefleischten C-Programmierer, die brauchen das ganz offensichtlich.
Zeno schrieb: > Ja und genau deswegen fallen viele Anfänger erst mal so richtig auf die > Fresse. Nö. Die nehmen nämlich heutzutage Arduino, und da die fix-und-fertig-rundum-glücklich "delay()"-Funktion. Irgendwelche Zeitvertrödelungs-Schleifen baut da keiner mehr selber.
Gast
#7189414
Zeno schrieb: > Ja und genau deswegen fallen viele Anfänger erst mal so richtig auf die > Fresse. Oh. Eine Programmiersprache muß man tatsächlich lernen. Unglaublich, das ist ja fast wie im richtigen Leben.
Zeno ist halt einfach ein paar Jahre zu früh dran. Irgendwann, wenn die KI-Basierten Codegeneratoren ein Bewusstsein entwickelt haben und brauchbare Ergebnisse liefern, kann auch er seinen gedankenlesenden Do-What-I-Want Compiler haben.
Gast
#7189423
Zeno schrieb: > Ich merke aber schon, das ich hier gegen Windmühlen kämpfe und die > Fangemeinde dieses Verhalten toll findet und lieber volatile > hinschreibt Ja, natürlich. Die Freiheit, die der Compiler ganz absichtlich hat, erlaubt ihm nämlich überhaupt erst etliche Optimierungen. Ob er die Variable im Register hält oder auf dem Stack etwa - und beides wird die Zeit so oder so erheblich beeinflussen. Genau dafür ist die as-if-Regel da. Ganz einfach. Das hat nichts mit "lieber volatile hinschreiben" zu tun, sondern damit, daß auch Du auf einem ganz grundlegenden Level nicht verstehst, was C überhaupt ist.
Zeno schrieb: > Ich erwarte schlichtweg das er den von mir hingeschriebenen Quelltext, > solange er gültigen Code darstellt, in ausführbare Instruktionen für die > CPU umsetzt, aber nicht entscheidet das der hingeschriebene Code > eigentlich, nach seiner Ansicht, überflüssig ist und ihn deswegen > einfach weg läßt Dann darfst du ihn halt nicht optimieren lassen, -O0 als Option. Dann macht er genau diese Tippeltappeltour und setzt alles 1:1 um. Das Resultat ist halt riesig groß und schweinelangsam, aber es entspricht dem, was du hingeschrieben hast. Wenn du ihn dagegen optimieren lässt, dann sagst du ihm, dass er Dinge einfacher ausdrücken soll, als sie hingeschrieben worden sind. Wenn du nun einzelne Dinge doch nicht optimiert haben willst, musst du das dem Compiler mitteilen. "volatile" wurde schon genannt, ich hatte auf die Möglichkeit des Einstreuens von Inline-Assembler-Code (NOP) hingewiesen. Wie sinnvoll das dann ist, darüber lässt sich natürlich vortrefflich streiten, denn je nach CPU-Caching-Möglichkeiten kann das Resultat trotzdem noch rasend schnell abgearbeitet werden. Aber so ein "do what I mean"-Compiler, also "optimiere überall außer da, wo ich mir gedacht (aber es nicht geschrieben) habe, dass du nicht optimieren sollst" muss wohl erst noch erfunden werden.
Gast
#7189554
Jörg W. schrieb: > Dann darfst du ihn halt nicht optimieren lassen, -O0 als Option. Das ist allerdings Compiler-spezifisch, der C-Standard selber sieht derlei nicht vor. Prinzipiell dürfte ein C-Compiler also auch bei abgeschalteten Optimierungen solche Leerschleifen rauswerfen. Wenn der Code mit Optimierungen kaputt ist, dann ist es es nämlich auch ohne Optimierungen immer noch.
Nop schrieb: > Das ist allerdings Compiler-spezifisch, der C-Standard selber sieht > derlei nicht vor. Ist natürlich richtig, aber ist dir schon mal ein Compiler über den Weg gelaufen, der keine Möglichkeit hat, die Optimierungen abzuschalten? Ich vermute, dass man das während der Implementierung eines Compilers ohnehin benötigt.
Und auch der GCC unterlässt mit -O0 nicht alle Optimierungen Sonst müsste am AVR eine Schleife
1 | |
eine andere Frequenz ausgeben als
1 | |
weil die Bitshifts am AVR unterschiedlich lange brauchen. Aber der bösartige, verbrecherische Compiler setzt da trotz -O0 einfach eine vorberechnete Konstante ein, obwohl es anders in Quelltext steht!
:-)
Gast
#7189666
Jörg W. schrieb: > aber ist dir schon mal ein Compiler über den Weg > gelaufen, der keine Möglichkeit hat, die Optimierungen abzuschalten? Nee, das nicht, aber wenn ich schon die Wahl habe, ob ich nach C-Standard programmiere oder mich auf ein bestimmtes Verhalten eines bestimmten Compilers verlasse, wähle ich Ersteres, weil Letzteres gerne später zu Problemen führt. Etwa mit Portabilität oder auch nur einem schnöden Compiler-Update. Ich erinnere nur an die Story, wo GCC irgendwo bei 4.9 strict-aliasing zum Default gemacht hat und Torvalds sich aufgeregt hat, weil das Kernel Team erstens mit Pointer-Aliasing gearbeitet hatte sowie zweitens bei der Build-Chain geschlampt und das nicht explizit angewiesen hatte. Dann funktionierte es auf einmal nicht mehr. Oder ganz typisch bei embedded: Mist, der Code paßt mit den neuen Features nicht mehr ins Flash, laß mal mit -Os die Größe reduzieren. Ooops, der auch vorher schon kaputte Code geht jetzt nicht mehr.
Nop schrieb: > laß mal mit -Os die Größe reduzieren. Naja, wer im Embedded-Bereich nicht genau das von vornherein so macht, der tut mir leid. Nicht optimierter Code auf dem PC ist schon Mist, aber auf einem Controller ist es pure Geldverschwendung.
Gast
#7189703
Jörg W. schrieb: > Naja, wer im Embedded-Bereich nicht genau das von vornherein so macht, > der tut mir leid. Soviel also zum Thema "Optimierungen abschalten".
Gast
#7189752
Also ich versteh den Zeno schon irgendwie. Es gibt Optimierungen, für die man zumindest selber keine sinnvolle Anwendung sieht. Eine Schleife wegzuoptimieren würde für mich dazu gehören. Aber es kann natürlich sein, dass es die Anwendung doch gibt, Makros wurden hier ja schon angedeutet, auch Konstanten könnten in einer Schleife verrechnet werden, das dann der Compiler schon vollständig erledigen kann. Auch dass solche grenzwertigen Spezialfälle vom Compiler als solche erkannt werden müssten, was ein zusätzlicher Entwicklungsaufwand wäre, ist für mich ein nachvollziehbares Argument. Philipp Klaus K. schrieb: > An SDCC wird häufig kritisiert, dass es jede > Funktion, die in einer Quellcodedatei steht, auch in die Binärdatei > kompiliert [...], selbst wenn die betreffende > Funktion gar nicht aufgerufen wird. Da geht es also nicht mal um ein > einzelnes ++ oder eine leere Schleife, sondern um ganze Funktionen, von > denen die Programmierer erwarten, dass der Compiler diese wegoptimiert! Das versteh ich gut. Man versucht ja wiederverwendbaren Code zu schreiben bzw. versucht Code wiederzuverwenden und dazu gehört halt, dass man auch Funktionen hat, die man im aktuellen Projekt gerade nicht benötigt. Für Bibliotheken gilt das sowieso, auch wenn sie als Quellcode vorliegen.
Maxe schrieb: > Eine Schleife > wegzuoptimieren würde für mich dazu gehören. Aber optimieren, dass sie schneller läuft, darf er? d.H. die Schleife in ein einziges "NOP" zu reduzieren wäre OK, sie ganz wegzulassen ist nicht sinnvoll? IAW: Wäre es für dich OK, wenn der Compiler aus
1 | |
2 | |
ein
1 | |
macht? Oder ist das nicht sinnvoll? Oder macht es dir Angst, dass der Compiler diese Optimierungsmöglichkeit gesehen hat?
Nop schrieb: > Soviel also zum Thema "Optimierungen abschalten". Naja, du warst doch derjenige, der unbedingt eine 1:1-Umsetzung haben will. Die geht, wenn man die Optimierung ausschaltet. Ich bin nur derjenige, der sagt, dass ich das im Embedded-Bereich nicht sinnvoll finde.
Gast
#7190029
Jörg W. schrieb: > Naja, du warst doch derjenige, der unbedingt eine 1:1-Umsetzung haben > will. Äh, nein? Das waren Zeno und W.S., während ich derjenige war, der sich lieber an den C-Standard hält. Und Dein Vorschlag war es doch, mit -O0 die Optimierungen auszuschalten: > Dann darfst du ihn halt nicht optimieren lassen, -O0 als Option. Aber wenn man sich nicht an den C-Standard hält, meckert man, daß die Optimierungen den Code kaputtmachen, obwohl er selbstverständlich schon vorher kaputt war. Wenn man daher ohne Optimierungen arbeitet, anstatt den Code zu fixen, dann rennt man später im Projekt u.U. genau in die von mir beschriebene Situation: Code ist zu groß, und mit -Os geht er nicht mehr.
Nop schrieb: >> Naja, du warst doch derjenige, der unbedingt eine 1:1-Umsetzung haben >> will. > > Äh, nein? Oh, 'tschuldigung, stimmt.
Gast
#7190754
Jörg W. schrieb: > GCC hatte früher für diesen Konstrukt tatsächlich eine "Sonderlocke" > implementiert, aber das war zusätzlicher Aufwand, just diese Situation > ("toter Code, der stehen bleiben soll") zu erkennen, und irgendwann > haben sie halt diese Sonderlocke abgeschafft. Tja, aber in der typisch inkonsequenten Weise der C-"Logik" natürlich nicht sehr konsequent. Denn, in:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
wird die Schleife trotz ihrer offensichtlichen Nutzlosigkeit NICHT wegoptimiert. Nach der von dir beschriebenen "superlogischen Logik", die so typisch für dieses unsäglich erbärmliche C-Gefrickel ist, hätte sie aber wegoptimiert werden müssen! Denn klarerweise geschieht im Body nichts nützliches, d.h.: auch die diesen Body umfassende Kontrollstruktur ist unnütz, denn eine Schleife, die unendlich garnix macht, macht am Ende garnix. Tja, so ist das mit der Logik...
Gast
#7190764
c-hater schrieb: > hätte sie aber wegoptimiert werden müssen! Nope. Ohne Endlosschleife gibt's nämlich einen beobachtbaren externen Effekt: Das Programm endet. Bei den Delay-Schleifen gibt's so einen Unterschied nicht. Erst denken, dann ranten.
Gast
#7190778
Nop schrieb: > Nope. Ohne Endlosschleife gibt's nämlich einen beobachtbaren externen > Effekt: Das Programm endet. Bei den Delay-Schleifen gibt's so einen > Unterschied nicht. Erst denken, dann ranten. Nur ist das Problem: an jeder anderen Stelle im Programm wird EXAKT dieselbe Schleife wegoptimiert. Was ist denn das für ein Sprachstandard? Einmal hüh, einmal hott bei EXAKT demselben Sprachkonstrukt? Das ist lächerlich für einen Sprachstandard!
> Nur ist das Problem: an jeder anderen Stelle im Programm wird EXAKT > dieselbe Schleife wegoptimiert. seit wann das? Alles was nach
1 | |
kommt, kann natürlich wegoptimiert werden (non-reachable code). Jörg
Joerg W. schrieb: > seit wann das? Warum sollte jemand, der sich "c-hater" nennt, sich mit C auskennen (geschweige denn mit dessen Standard)?
Gast
#7191527
Jörg W. schrieb: > Naja, du warst doch derjenige, der unbedingt eine 1:1-Umsetzung haben > will. > > Die geht, wenn man die Optimierung ausschaltet. Moin, bist Du sicher, dass der von Dir verwendete Compiler bei -O0 wirklich den kompletten Code 1:1 übersetzt? z.B. der C/C++ Development Guide zum IAR Compiler für Arm v9.30.1 sagt auf Seite 250 zu den Optimierungen:
1 | |
2 | |
3 | |
4 | |
5 | |
Also wird bereits bei "Optimization = none" bis zu einem gewissen Punkt nur das übersetzt, was am Ende auch Sinn macht und nach meinem Verständnis sollte das vom C Standard (z.B. C99 - 5.1.2.3) abgedeckt sein. z.B. wird für das Incrementieren von foo kein Code mehr erzeugt, da die Instruktion "unreachable" ist (aber es wird zumindest eine entsprechende Warnung angezeigt):
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
@ Philipp: Wie handhabt das denn der SDCC? Gruß, Michael
Michael F. schrieb: > bist Du sicher, dass der von Dir verwendete Compiler bei -O0 wirklich > den kompletten Code 1:1 übersetzt? Naja, es wurde ja weiter oben schon angemerkt, dass insbesondere die Konstantenberechnung trotzdem noch zur Compilezeit erfolgt. Bei dead code elimination wäre ich mir jetzt nicht ganz so sicher, ich glaube, die macht ein GCC (und vermutlich auch Clang) nur mit Optimierungsniveau größer 0, da bei -O0 keinerlei Codeflussanalyse vorgenommen wird. Übrigens sollte man dort zumindest schon aus diesem Grunde mit mehr als -O0 arbeiten, denn eine ganze Reihe von Warnungen können sonst gar nicht generiert werden … Klar, der C-Standard äußert sich nicht zu Optimierungen, die sind da "out of scope", da gilt die "as if"-Regel.
Michael F. (Firma: IAR Systems) schrieb: > Wie handhabt das denn der SDCC? Dürft Ihr bei IAR keinen SDCC benutzen? :)
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
Übersetzt in ASM code mit ...
1 | |
2 | |
3 | |
4 | |
... ergibt dann in dc.asm:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
Für Z80 ist das Ergebnis ähnlich, 18 FE
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
Gast
#7191820
Joerg W. schrieb: > seit wann das? Keine Ahnung. > Alles was nach >
1 | |
2 | |
> kommt, kann natürlich wegoptimiert werden (non-reachable code).
Ja, das ist ja auch logisch und somit sinnvoll. Keine Einwände
meinerseits.
Ich meine sowas (absichtlich eingebauter "trap"):
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
Was tatsächlich rauskommt, ist aber, dass die gewollte Endlosschleife ersatzlos rausoptimiert wird und statt dessen unmittelbar der Code hinter dem Else-Zweig der Verzweigung ausgeführt wird. Ist allerdings errordetected != true, wird erwartungsgemäß der "normal behavior" durchlaufen (und macht auch, was er soll) und erst dann der Code hinter der Verzweigung.
Gast
#7191834
Εrnst B. schrieb: > Irgendwann, wenn die KI-Basierten Codegeneratoren ein Bewusstsein > entwickelt haben und brauchbare Ergebnisse liefern, kann auch er seinen > gedankenlesenden Do-What-I-Want Compiler haben. Wieso muß der Compiler GEdanken lesen? Der soll nur machen was ich ihm auf den "Einkaufszettel" schreibe. Im Übrigen gibt es einen solchen Compiler schon seit ca. 1971. Der tut das was ich ihm hin schreibe - ist halt kein C.
Gast
#7191843
Jörg W. schrieb: > Warum sollte jemand, der sich "c-hater" nennt, sich mit C auskennen > (geschweige denn mit dessen Standard)? Ich befürchte mal das sich der c-heater mit C besser auskennt als Du denkst und nur durch die Besonderheiten diese Sprache zum c-hater geworden ist. Michael F. schrieb: > z.B. wird für das Incrementieren von foo kein Code mehr erzeugt, da die > Instruktion "unreachable" ist (aber es wird zumindest eine entsprechende > Warnung angezeigt): So wäre das ja auch für mich in Ordnung - mit der Warnung, weil dann entscheide ich ob an dieser Stelle "optimiert" wird oder nicht.
Gast
#7191857
c-hater schrieb: > Was tatsächlich rauskommt, ist aber, dass die gewollte Endlosschleife > ersatzlos rausoptimiert wird und statt dessen unmittelbar der Code > hinter dem Else-Zweig der Verzweigung ausgeführt wird. Ist das so? Gerade mal auf Godbolt geguckt für ARM-GCC 12.1 mit -O3. Dieser Codeschnipsel hier...
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
... wird compiliert zu:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
Es wird also die Endlosschleife ausgeführt, wenn errordetected ungleich 0 ist, und sonst die Dummy-Variable erhöht.
Gast
#7191863
Ich vermute daher, daß in was auch immer Dein Beispiel ursprünglich getan hat, der Fall des errordetected deswegen gar nicht auftreten kann, weil Du dann undefined behaviour eingebaut hättest und der Compiler das erkannt hat. Dann darf der Compiler diesen Fall behandeln, wie immer er das möchte. Das ist ein Fehler im Code, wenngleich C99 knapp 200 Fälle von undefined behaviour hat und man das zurecht kritisieren kann, insbesondere weil man nicht immer eine Warnung dazu bekommt. In dieser Hinsicht macht Rust es besser.
Gast
#7191864
c-hater schrieb: > Was ist denn das für ein Sprachstandard? Einmal hüh, einmal hott bei > EXAKT demselben Sprachkonstrukt? Naja für die main() braucht man halt ab und an mal ne Endlosschleife um goto zu vermeiden. Obwohl dafür gäbe es ja auch for(;;){} - ist genau so hirnrissig.
Gast
#7191868
Zeno schrieb: > Obwohl dafür gäbe es ja auch for(;;){} - ist genau so hirnrissig. Nein, ist es nicht. Es ist deswegen die von K&R propagierte und die einzige von Lint akzeptierte Form, weil man bei einer while-Schleife die Schleifenbedingung aus Versehen auf endlos stellen kann, besonders im Zusammenspiel mit Macro-Defines. Bei der Form mit for(;;){} gibt's dieses Risiko nicht.
Zeno schrieb: > Ich befürchte mal das sich der c-heater mit C besser auskennt als Du > denkst Diesen Eindruck hat er bei mir im Laufe der Zeit keineswegs hinterlassen.
Nop schrieb: > Es wird also die Endlosschleife ausgeführt, wenn errordetected ungleich > 0 ist, und sonst die Dummy-Variable erhöht. Zumal es derartige Endlosschleifen auch sonst immer mal gibt, beispielsweise die default-Handler für allerlei Exceptions beim ARM sind typischerweise genau sowas. Und die werden natürlich von keinem Compiler weg optimiert. Hier aus dem Atmel-ARM-Sourcecode:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
Gast
#7192066
Jörg W. schrieb: > Diesen Eindruck hat er bei mir im Laufe der Zeit keineswegs > hinterlassen. Der Eindruck kann manchmal auch täuschen. Nop schrieb: > Zeno schrieb: >> Obwohl dafür gäbe es ja auch for(;;){} - ist genau so hirnrissig. > > Nein, ist es nicht. Es ist deswegen die von K&R propagierte und die > einzige von Lint akzeptierte Form, weil man bei einer while-Schleife die > Schleifenbedingung aus Versehen auf endlos stellen kann, besonders im > Zusammenspiel mit Macro-Defines. Bei der Form mit for(;;){} gibt's > dieses Risiko nicht. Ja logo finden die Fans der Sprache C so was geil, weil so etwas ohne jegliche Logik ist, man muß es halt auswendig lernen. Man kann jede Schleife zu einer Endlosschleife machen, wenn man die Abbruchbedingung entsprechend setzt. Ob das wissentlich, versehentlich oder gar gewollt gemacht wird ist dabei völlig Rille.
Zeno schrieb: > Man kann jede Schleife zu einer Endlosschleife machen, wenn man die > Abbruchbedingung entsprechend setzt. Klar kannst du das. Hier geht es ausschließlich darum, 1) welche Gepflogenheiten es (aus was auch immer für Gründen) schon gibt und 2) was entsprechende Syntaxchecker vorzugsweise erwarten. (Beides hängt natürlich zusammen.) Das ist halt die "for (;;)"-Form, da sie praktisch nie versehentlich "entstehen" kann. Der eher seltene Fall einer Endlosschleife *) ist es gewiss nicht wert, dass man ihm nun einen eigenen Sprachkonstrukt widmet – das wäre ja die "offizielle" Alternative. *) Im Kontext einer HDL sieht das anders aus, aber wir reden hier über Programmiersprachen.
Gast
#7192087
So ein Compiler kann schon unterscheiden zwischen einer Endlosschleife und einer Schleife die nur eine (vermutlich danach nicht mehr verwendete) Variable hochzählt. Ersteres soll nie enden, das letztere soll so schnell wie möglich ausgeführt werden, als am besten mit 0 Takten. Und es gibt eine (indirekte) Möglichkeit dem Compiler zu sagen, daß man den Zählvorgang doch haben will, vermutlich weil man Zeit verbrennen will. Wo ist also das Problem. Wer diese Sprache nicht mag, der soll es einfach lassen. So wie ich die Sprache Baujahr 1971 nicht (mehr) benutze, das aber normalerweise jedem verheimliche. Auch Fe2O3 brauch ich nicht, aber auch das will ich niemandem erklären.
Gast
#7192542
Gcc schrieb: > Wo ist also das Problem. Wer diese Sprache nicht mag, der soll es > einfach lassen. So wie ich die Sprache Baujahr 1971 nicht (mehr) > benutze Genauso ist es, jeder soll auf seine Art glücklich werden. Gcc schrieb: > das aber normalerweise jedem verheimliche Warum das? Muß man sich rechtfertigen wenn man diese Sprache nicht mag?
Gast
#7193144
Jörg W. schrieb: > Hier geht es ausschließlich darum, 1) welche Gepflogenheiten es (aus was > auch immer für Gründen) schon gibt und 2) was entsprechende > Syntaxchecker vorzugsweise erwarten. (Beides hängt natürlich zusammen.) > Das ist halt die "for (;;)"-Form, da sie praktisch nie versehentlich > "entstehen" kann. Nun ja, Gepflogenheiten sind etwas, das nicht aus rationaler Überlegung entsteht, sondern eben nur aus 'das mache ich nach'. So wie bei Hobby-Tischlern, daß sie ihren Hobel NIE gerade auf ihren Basteltisch stellen, sondern immer nur auf die Seite legen. Irrational? Ja. Eben wie alle Gepflogenheiten. Aber herzlich egal. Allerdings sieht das bei solchen Konstrukten wie for(;;) aus logischer Sicht anders aus, als du es darstellst. Von einem Sprachkonstrukt erwartet man eigentlich, daß es zu einem bestimmten Zweck existiert. So ist der eigentliche Zweck von 'for' eben, eine abgezählte Schleife zu machen und der von 'while' eine unabgezählte Schleife, aber mit einer Abbruchbedingung. So etwas zu korrumpieren, indem man die Abzählung oder die Abbruchbedingung hintertreibt, wird in C zwar nicht als Programmierfehler gewertet, führt aber dennoch zu einer entarteten Schleife, der ein wesentlicher Teil fehlt. Es ist unlogisch, ein Sprachkonstrukt zu verwenden, dessen Zweck man garnicht bezweckt. Da können K&R dazu sagen, was sie wollen. Was da bleibt ist eben nur die Gepflogenheit. Und die ist irrational. Genauso wie der Streit darum, an welchem Ende man das Ei aufschlägt. W.S.
W.S. schrieb: > Allerdings sieht das bei solchen Konstrukten wie for(;;) aus logischer > Sicht anders aus, als du es darstellst. Du hast nur eine Seite meiner Darstellung einbezogen – die andere Seite, dass eine "for(;;)"-Schleife halt niemals "aus Versehen" (auch nicht durch irgendwelche Makroerweiterungen etc.) entsteht, hast du ignoriert. Diese dürfte aber wesentlich dazu beigetragen haben, dass diese Gepflogenheit halt überhaupt so entstanden ist und dass sich Syntaxchecker (wie Lint) daran orientiert haben, eine solche Schleife nicht als potenziellen Programmierfehler zu warnen. Kommt natürlich noch dazu, dass Endlosschleifen außerhalb von "deep embedded" nur sehr selten benutzt werden. Es ist also mittelmäßig müßig, sich nun ausgerechnet an solch einem Detail hier aufzugeilen. Es gibt Dinge in C, die in die Kategorie "historisch gewachsen aber praktisch nicht mehr zu ändern" fallen, die viel wesentlicher wären, beispielsweise dass die Sichtbarkeit einer nicht näher auf Toplevel einer Übersetzungseinheit bezeichneten Variablen oder Funktion global statt modulintern ist. Aus heutiger Sicht hätte man das lieber anders herum gehabt, also explizite Deklaration all dessen, was über den Modul hinaus geht.
Gast
#7193280
Zeno schrieb: > Gcc schrieb: >> das aber normalerweise jedem verheimliche > Warum das? Muß man sich rechtfertigen wenn man diese Sprache nicht mag? Was hat das mit Rechtfertigung zu tun, wenn man nicht jedem seine eigenen Vorlieben andienen will.
W.S. schrieb: > So ist der eigentliche Zweck von 'for' eben, eine abgezählte Schleife zu > machen Nö. Eine Zählung mittels i++ in einer for-Schleife ist lediglich ein Spezialfall einer Anwendung von einer for-Schleife. Das Konstrukt "for" in C ist aber wesentlich allgemeiner gefasst. Die Verwendung einer Zählvariablen in einer for-Schleife wird zwar der meiste Anwendungsfall sein (weil es so am bequemsten ist), trotzdem ist dieses nicht der "eigentliche Zweck". Nur ein Gegenbeispiel von tausenden:
1 | |
Wir sprechen hier nicht über Basic oder Pascal, wo eine for-Schleife tatsächlich explizit bzw. implizit über eine Zählvariable läuft. Und ich halte es auch für einen Fehler, Eigenschaften von anderen Programmiersprachen auf C zu projizieren zu wollen. Das führt nur zu einer Einschränkung - nämlich seines eigenen Denkapparates.
Frank M. schrieb: > Nur ein Gegenbeispiel von tausenden: > for (ptr = obj->start; *ptr; ptr = obj->next) Besser so?
1 | |
Gast
#7198950
Martin H. schrieb: > Besser so? Sehe ich auch so. Besser.
Gast
#7198955
Martin H. schrieb: > for (ptr = obj->start; ptr && *ptr; ptr = ptr->next) Nicht eher so? for (ptr = obj->start; ptr; ptr = ptr->next)
Gast
#7198965
Wobei, ich habe auch schon diese Variante gesehen:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
Martin H. schrieb: > Besser so? > for (ptr = obj->start; ptr && *ptr; ptr = ptr->next) Sorry, ja, natürlich, wobei ich ptr alleine meinte - ohne Sternchen und auch ohne die 2. Bedingung. Letztere kommt meist auf den Kontext an. :-)
Meine Antwort: Beitrag "microchip c18 vs. sdcc" Ich war noch zufrieden. Dann habe ich für meine Anwendungen einen Interpreter entwickeln um möglich schnell zu Lösungen zu kommen. Im Interpreter sind Menüs im Rom beschrieben. Und dann kam zum Einsicht dieser Fehler: https://sourceforge.net/p/sdcc/bugs/2589/ Zur Zeit keine Lösung. Trotzdem arbeite ich weiter mit SDCC.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.