Gast
#2582691
Guten Morgen Forum! Wie darf man folgende Verwendung der while-Schleife verstehen?
1 | |
2 | |
3 | |
4 | |
5 | |
|
Anzeige
|
while-Schleife
Gast
#2582691
Guten Morgen Forum! Wie darf man folgende Verwendung der while-Schleife verstehen?
Gast
#2582694
Na ja, so wie es dasteht.. --> Es ist einfach nur eine Endlosschleife, in dem dein Programm nichts macht :-) Die Schleifenbedingung ist immer erfüllt. => Endlosschleife
Gast
#2582706
Da die Bedingung der while-Schleife immer erfüllt ist (blöde Frage: wieso ist "1" immer erfüllt?) und keine Anweisungen in der Schleife vorhanden sind, bleibt das Programm in der Schleife stehen und wartet --> Endlosschleife. Richtig?
Gast
#2582708
Do Ma schrieb: > blöde Frage: > wieso ist "1" immer erfüllt?) weil alles was != 0 = true ist.
Gast
#2582713
Do Ma schrieb: > blöde Frage: wieso ist "1" immer erfüllt? Alles ungleich 0 wird von der Schleife als "erfüllt" interpretiert :-) So, wie du deinen Code geschrieben hast, funktioniert es nicht, da deine
wegoptimiert wird... Probiere doch lieber mal soetwas hier:
Gast
#2582717
Stefan schrieb: > So, wie du deinen Code geschrieben hast, funktioniert es nicht, da deine > while(1) > { > > } > wegoptimiert wird... nein das passiert nicht, der compiler darf nichts wegoptimiert was das verhalten ändert.
Gast
#2582718
Ein Semikolon obwohl keine Anweisung vorhanden ist!? Ok.
Gast
#2582722
Peter II schrieb: > nein das passiert nicht, der compiler darf nichts wegoptimiert was das > verhalten ändert. Und was genau ändert sich am Verhalten, wenn eine sinnlose while-Schleife wegoptimiert wird??? Schau dir am besten mal das Listing an.
Gast
#2582726
Do Ma schrieb: > Ein Semikolon obwohl keine Anweisung vorhanden ist!? Ok. Eleganter ist es natürlich so:
Das wird der Compiler mit Sicherheit nicht wegoptimieren.
Gast
#2582731
Interessant wäre dazu vielleicht diese Lektüre: http://de.wikipedia.org/wiki/Compiler#Optimierung_von_Schleifen In diesem Fall trifft Punkt 8 ziemlich genau zu...
Gast
#2582741
Stefan schrieb: > Und was genau ändert sich am Verhalten, wenn eine sinnlose > while-Schleife wegoptimiert wird??? das der code danach erreicht wird ist schon ein unterschied. Stefan schrieb: > In diesem Fall trifft Punkt 8 ziemlich genau zu... Nochmal: Der Compiler darf beim Optimieren nichts weglassen, wenn das das Verhalten des Programms ändern würde. Er darf z.B. while(1); durch einen "HALT"-ASM-Befehl ersetzen, wenn die CPU einen solchen besitzt. => Beides verhindert, dass Code, der nach der Schleife steht, ausgeführt wird. Er darf auch allen Quelltext, der in der funktion nach der Schleife steht, entfernen, "unreachable code". Aber er darf nicht einfach die Schleife weglassen, und so tun als stände da nix.
Gast
#2582743
Stefan schrieb: > Eleganter ist es natürlich so: > while(1) > { > asm volatile ("nop"); > } assember in einer Hochsprache zu verwenden ist also Elegant? Was ist wenn die plattform gar kein nop hat?
Gast
#2582749
Stefan schrieb: > In diesem Fall trifft Punkt 8 ziemlich genau zu... nein macht es nicht, denn eine entlosschleife ist keine normale schleife.
Gast
#2582769
Alle die sich jetzt über die Wegoptimierung beschweren: NOCHMAL LESEN!!! Es ging ausdrücklich um dieses Konstrukt:
NICHT um dieses hier:
Spätestens jetzt sollte dann die Sonne aufgehen :-)
Gast
#2582772
Peter II schrieb: > assember in einer Hochsprache zu verwenden ist also Elegant? Was ist > wenn die plattform gar kein nop hat? Nenn mir bitte eines... Stefan schrieb: > In diesem Fall trifft Punkt 8 ziemlich genau zu... Na was denn jetzt? Entweder es trifft zu oder es trifft nicht zu. "Ziemlich genau" gibt es in der Digitaltechnik und beim Programmieren nicht. Und eine Auf-der-Stelle-Trampel-Schleife wird niemals wegoptimiert. mfg.
Gast
#2582781
Stefan schrieb: > Nenn mir bitte eines... zeig mir erstmal einen compieler der while(1) {} oder while(1); wegoptimiert. (gcc macht es zumindest schon mal nicht) Peter II schrieb: > gcc macht es zumindest schon mal nicht Kein C-Compiler macht das. Weil es sonst kein C-Compiler wäre. mfg. Stefan schrieb: > Spätestens jetzt sollte dann die Sonne aufgehen Hoffe ich. Spätestens wenn du feststellst, dass in C diese drei Konstrukte komplett identisch sind:
und zusätzliche Leerzeichen, Einrückungen, Zeilenumbrüche ändern auch nichts daran. Alle drei macht der Compiler zu:
o.Ä. Das hier hat übrigens auch denselben Effekt
Gast
#2582813
Thomas Eckmann schrieb: > Stefan schrieb: >> In diesem Fall trifft Punkt 8 ziemlich genau zu... > Na was denn jetzt? > Entweder es trifft zu oder es trifft nicht zu. > "Ziemlich genau" gibt es in der Digitaltechnik und beim Programmieren > nicht. @Thomas Eckmann: Gaaaaaanz ruhig. Nur für dich kann ich es gerne umformulieren: Punkt 8 trifft zu. > Und eine Auf-der-Stelle-Trampel-Schleife wird niemals wegoptimiert. Dann lese den Code NOCHMAL (und diesmal aufmerksam) durch. Das ist KEINE Auf-der-Stelle-Trampel-Schleife sondern ein Schleife-mit-total-leerem-Rumpf. Thomas Eckmann schrieb: > Kein C-Compiler macht das. Weil es sonst kein C-Compiler wäre. Selbst gcc macht das, und das auch noch zurecht :-) Gerne kann ich eine kleine Wette vorschlagen: Ich bringe Euch den Beweis, und jeder der hier dumm ohne Ahnung rumheult zahlt mir meinen Stundensatz......
Gast
#2582822
@Stefan dann zeige uns in beispiel, ich habe es selber getestet und habe es nicht hinbekommen das er es wegoptimiert. Und wenn hier alle Personen einer anderen Meinung sind dann würde ich schon mal fragen warum? Für so ein beispiel braucht du bestimmt keine 2minuten - bei 100€/h sind das knapp 4€. Dann legen wir mal alle zusammen. Stefan schrieb: > Selbst gcc macht das, und das auch noch zurecht
macht der gcc zu:
Wo ist das printf? Und überweist du mir jetzt meinen Stundensatz? Sorry Namensvetter, aber du schteibst echt Unsinn. Insbesondere existiert der Unterschied, den du da zu konstruieren versuchst, gar nicht. Deine beiden while Varianten oben sind absolut identisch. Εrnst B✶ schrieb: > Wo ist das printf? Und überweist du mir jetzt meinen Stundensatz? lol Thema verfehlt, setzen 6 es geht doch darum das das kein Compiler der Welt weg optimiert! Εrnst B✶ schrieb: > .L2: > jmp .L2 Manfred John schrieb: > es geht doch darum das das kein Compiler der Welt weg optimiert! Genau das habe ich doch gezeigt. Der Compiler hat die While-Schleife drinnen gelassen, und stattdessen das Printf wegoptimiert. Stefan behauptet/wettet, dass der Compiler das while weglässt, und stattdessen das printf ausführt. Das habe ich widerlegt. Stefan schrieb: > Gaaaaaanz ruhig. Nur für dich kann ich es gerne umformulieren: Punkt 8 > trifft zu Jetzt halt' dich mal ein bischen zurück. Stefan schrieb: > Selbst gcc macht das, und das auch noch zurecht :-) Gerne kann ich eine > kleine Wette vorschlagen: Ich bringe Euch den Beweis, und jeder der hier > dumm ohne Ahnung rumheult zahlt mir meinen Stundensatz...... Angenommen. Wo soll ich meine Rechnung hinschicken? void Inititialize(void) { ... while(1); } ... 170: ff cf rjmp .-2 ; 0x170 <Initialize+0x64> Und dann erklärst du mal, wie man ein rein interruptgesteuertes Programm aufbaut, einen Watchdog-Reset erzwingt oder wie man einen Controller in einem definierten Zustand anhält. Da sind wir jetzt alle sehr gespannt. mfg. Stefan hat vermutlich auf einer Cray das Programmieren gelernt. Die haben ja bekanntlich auch eine Endlosschleife innerhalb von 6 Stunden abarbeiten können. #Ernst SORRY,hab mich da vergugt, dachte das kam von Stefan. (Wird zeit das ich ne Mütze voll Schlaf bekomme) Do Ma schrieb: > Ein Semikolon obwohl keine Anweisung vorhanden ist!? Ok. Das Semikolon IST die Anweisung. Auch in C gibt es die leere Anweisung. technisch gesehen gehört in
das Semikolon nicht zum while, sondern bildet seine eigene, eben die leere Anweisung. Folgt man den üblichen Formatierregeln, die besagen, dass die abhängige Anweisung im Fall einer Schleife in die nächste Zeile kommt und eingerückt wird, wie zb in
dann würde konsequenterweise diese Endlosschleife so geschrieben ...
... den die abhängige Anweisung besteht nur aus der leeren Anweisung, die durch ein Semikolon abgeschlossen wird. Stefan schrieb: >> Und eine Auf-der-Stelle-Trampel-Schleife wird niemals wegoptimiert. > > Dann lese den Code NOCHMAL (und diesmal aufmerksam) durch. Das ist KEINE > Auf-der-Stelle-Trampel-Schleife sondern ein > Schleife-mit-total-leerem-Rumpf. Und? Du verwechselst da etwas. Ein Compiler kann eine Schleife nur dann wegoptimieren, wenn er nachweisen kann, dass sie NIE ausgeführt wird. Dazu ist es notwendig, dass er nachweisen kann, dass die Abbruchbedingung nie erfüllt werden kann bzw. nie TRUE ergibt. Das wird ihm allerdings bei einer Endlosschleife schwer fallen.
kann wegoptimiert werden. Aber
kann nicht wegoptimiert werden. Mit dem Inhalt des Schleifenrumpfes, wieviele und welche Anweisungen da enthalten sind, hat das so (in diesen beiden konkreten Fällen) erst mal nichts zu tun. Der kommt erst zum Tragen, wenn es eine Wechselwirkung des Schleifenrumpfes mit der Abbruchbedingung gibt oder nicht gibt.
Gast
#2582939
Peter II schrieb: > nein das passiert nicht, der compiler darf nichts wegoptimiert was das > verhalten ändert. Spätestens wenn man zusätzlich ASM verwendet, kommt man drauf, dass der Gedanke etwas naiv ist. Nicht umsonst gibt es das Schlüsselwort volatile. Hat jetzt aber natürlich nichts mit oben genannten Problem zutun. tomb schrieb: > Peter II schrieb: >> nein das passiert nicht, der compiler darf nichts wegoptimiert was das >> verhalten ändert. > > Spätestens wenn man zusätzlich ASM verwendet, kommt man drauf, dass der > Gedanke etwas naiv ist. Warum? Hat dir dein Compiler schonmal dein inline-ASM verhunzt? > Nicht umsonst gibt es das Schlüsselwort > volatile. Was dazu dient, dem Compiler mitzuteilen, dass sich eine Speicherstelle anders verhält als sich der C-Standard das vorstellt. d.H. Solang dein Rechner sich so verhält, wie der Compiler das erwartet, brauchst du volatile nicht, und es ändert auch nichts am Programmverhalten.
Gast
#2582967
Εrnst B✶ schrieb: > Was dazu dient, dem Compiler mitzuteilen, dass sich eine Speicherstelle > anders verhält als sich der C-Standard das vorstellt. volatile teilt den Compiler mit, das Speicherinhalte außerhalb in dem von ihm einsichtigen Programfluss verwendet werden können und deshalb nicht wegoptimiert werden dürfen. Und ja, das braucht man schon öfters mal. IRQs sind auch ein klassisches Beispiel dafür. tomb schrieb: > Peter II schrieb: >> nein das passiert nicht, der compiler darf nichts wegoptimiert was das >> verhalten ändert. > > Spätestens wenn man zusätzlich ASM verwendet, kommt man drauf, dass der > Gedanke etwas naiv ist. Nicht umsonst gibt es das Schlüsselwort > volatile. Das kommt immer drauf an, wie man "Verhalten" definiert und welche Vorschriften es für den Compiler gibt, die Umgebung einer Codestelle ins Kalkül zu ziehen. Und bei Assembler ist der Ofen sowieso aus. Zu diesem Thema hat der C-Standard im Grunde nur eines zu sagen: Ja, gibt es; aber für Details und Nebenwirkungen fragen sie ihren Compilerbauer oder die Doku. tomb schrieb: > Εrnst B✶ schrieb: >> Was dazu dient, dem Compiler mitzuteilen, dass sich eine Speicherstelle >> anders verhält als sich der C-Standard das vorstellt. > > volatile teilt den Compiler mit, das Speicherinhalte außerhalb in dem > von ihm einsichtigen Programfluss verwendet werden können und deshalb > nicht wegoptimiert werden dürfen. > > Und ja, das braucht man schon öfters mal. IRQs sind auch ein klassisches > Beispiel dafür. Du sprichst von speziellen C Implementierungen, während sich andere darauf konzentrieren möchten, was der Sprachstandard dazu zu sagen hat. Standard C hat keine Notation für IRQs oder Memory Mapped Devices oder atomaren Zugriff oder Interrupts im Generellen oder Shared Memory oder .... All das kommt im ISO Dokument nicht vor. Man hat sich auf ein paar Schlüsselwörter geeinigt und der gefordertes Verhalten definiert welche in den genannten Themenkreisen nützlich und notwendig sind, ohne diese Themenkreise selbst in den Standard mit aufnehmen zu müssen. Nicht die Dinge durcheinander werfen, sonst sind Missverständnisse vorprogrammiert.
Gast
#2586043
Wenn er das while(1); Wegoptimieren würde dann würde der PC einfach immer weiter inkrementiert und der Blödsinn der dahinter steht ausgeführt. Da nicht spezifiziert ist was dahintersteht würden eventuell komische Sachen passieren. Dannn würde irgendwann der PCam Ende des Speichers ankommen Überlaufen und wieder bei Adresse 0 anfangen (warscheinlich Reset vektor), das Programm würde erneut ausgeführt usw. Dies wäre (wenn es so wäre, was es nicht ist!) eindeutig eine Unzulässige Optimierung. Es ist halt schon ein unterschied ob ich einen Text auf dem UART ausgebe und danch in einer Endlosschlleife warte oder ob ich den Text ausgebe und danach nochmal ausgebe usw. Εrnst B✶ schrieb: > tomb schrieb: >> Peter II schrieb: >>> nein das passiert nicht, der compiler darf nichts wegoptimiert was das >>> verhalten ändert. >> >> Spätestens wenn man zusätzlich ASM verwendet, kommt man drauf, dass der >> Gedanke etwas naiv ist. Nö, das gilt immer noch. Wenn du mit deinem ASM-Code allerdings das Verhalten änderst ohne es dem Compiler mitzuteilen, ist dein Code fehlerhaft, nicht der Compiler. > Warum? Hat dir dein Compiler schonmal dein inline-ASM verhunzt? > >> Nicht umsonst gibt es das Schlüsselwort volatile. > > Was dazu dient, dem Compiler mitzuteilen, dass sich eine Speicherstelle > anders verhält als sich der C-Standard das vorstellt. Aber nicht bei "asm volatile". Da hat "volatile" es eine andere Bedeutung. Und in folgendem Beispiel auch:
Preisfrage Was ist die Ausgabe des obigen C-Programms? p.s. Einfach durch den Compiler jagen und schauen was der draus macht ist laaangweilig... Johann L. schrieb: > Was ist die Ausgabe des obigen C-Programms? Ich bekomme beim kompilieren Warnungen. Bitte erklär das Verhalten. ich kann es überhaupt nicht nachvollziehen, weiß aber auch nicht, was das volatile in dem Zusammenhang überhaupt für einen Zweck haben soll.
Gast
#2586938
Vlad Tepesch schrieb: > Ich bekomme beim kompilieren Warnungen. Alle Warnungen bekommt man zumindest bei gcc weg, indem man vor main() noch die Zeile einfügt:
Wieder was gelernt heute... Hoffentlich brauche ich das nie. Auf nen PC losgelassen zeigt das Programm ein nettes Verhalten ;-) Naja, laut ISO C ist das Verhalten undefiniert. Paßt also ;-) borg schrieb: > Alle Warnungen bekommt man zumindest bei gcc weg, indem man vor main() > noch die Zeile einfügt:
Bei mir gibt es dann die folgende Warnung mit gcc Version 3.4.5 (sowohl bei Übersetzung mit -Wall als auch ohne):
Gast
#2590257
Mark Brandis schrieb: > Bei mir gibt es dann die folgende Warnung mit gcc Version 3.4.5 (sowohl > bei Übersetzung mit -Wall als auch ohne): > > warning: `noreturn' function returns non-void value Das ist auch eine vernünftige Warnung (ich kann jetzt nicht nachvollziehen, warum ich die nicht bekommen habe). Es wäre aber kein Problem, ein ähnliches Beispiel zu schreiben, um ohne Warnungen ein undefiniertes Verhalten zu bekommen: Man lügt den Compiler an, indem man sagt: "Aus dieser (void-)Funktion wird nicht zurückgekehr, optimiere entsprechend." Sobald Aufrufer und Implementierer in unterschiedlichen Übersetzungseinheiten liegen, kann der Compiler diese Lüge kaum noch aufdecken und anwarnen. Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|