Gast
#6239899
1 | |
äquivalent zu?
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
|
Anzeige
|
while (1) Äquivalenz
Gast
#6239899
äquivalent zu?
Nein.
Gast
#6239913
Das eine läuft für immer, das andere nur bis der Stack voll ist.
Gast
#6239915
mh schrieb: > , das andere nur bis der Stack voll ist ;) Hallo? Text? Dankeschön? Tschüss? Kennste?
Gast
#6239923
10: goto 10
Gast
#6239932
for(;;);
Gast
#6239933
Keine Ahnung schrieb: > while (1) > äquivalent zu? > void FunktionA (void) > void FunktionB (void) > > void FunktionA() > { > FunktionB(); > } > > void FunktionB() > { > FunktionA(); > } C++: vermutlich Ja. C: vermutlich Nein. Vorausgesetzt es gibt irgendwo ein main(){functionA();} ...
Gast
#6239942
Warum der Weg über B und nicht gleich A rekursiv? JMP $
Gast
#6239952
Sowas geht nur in LISP gut. mh schrieb: > C++: vermutlich Ja. > C: vermutlich Nein. Eins von beiden ist vermutlich falsch. Oliver
Gast
#6239978
Oliver S. schrieb: > Eins von beiden ist vermutlich falsch. Wieso? Falls du es nicht wusstest
ist in c++ nicht erlaubt. Es geht also nur um die Rekursion ohne "forward progress"
Gast
#6239979
mh schrieb: > while(1){} > ist in c++ nicht erlaubt. Ja? Wo kann man das nachlesen?
Gast
#6239985
Der (endliche) Stack wird überlaufen.
Wenn eine Funktion aufgerufen wird, muss der Computer beim Verlassen der
Funktion rauskriegen, von wo aus die Funktion aufgerufen wurde, damit er
da weitermachen kann. Dafür wird er bei jedem Funktionsaufruf eine
Rücksprungadresse auf dem Stack ("Stapel") ablegen. Wenn eine Funktion
verlassen wird, wird diese Rücksprungadresse wieder entfernt.
Bei dir wird nie eine Funktion verlassen und daher die Rücksprungadresse
auch nie entfernt. Folglich wächst der Stack stetig weiter, bis eben
kein Speicher mehr da ist.
Du könntest das erreichen wie Ben sagt, indem du keine Funktionsaufrufe
verwendest, sondern direkt zu den Funktionen springst. Soweit ich weiß
müsstest du dann aber Assembler Instruktionen verwenden:
Du kannst ansonsten wie BumsFallera sagt, einfach keine Funktionen nutzen, sondern Label und dann das goto Schlüsselwort nutzen:
Gast
#6239986
Arduino Fanboy D. schrieb: > mh schrieb: >> while(1){} >> ist in c++ nicht erlaubt. > > Ja? > Wo kann man das nachlesen? http://eel.is/c++draft/intro.progress
und
Gast
#6240008
Du möchtest mir sagen, dass mein GCC 9.2 und auch alle gerade
erreichbaren Vorgänger defekt sind, weil sie bei "while(1){}" das zu
erwartende Verhalten (Endlosschleife), ohne jede Warnung, zeigen.
Ok ...
Gast
#6240015
Arduino Fanboy D. schrieb: > Du möchtest mir sagen, ... Nein, möchte ich nicht. Aber der gcc könnte etwas anderes machen, wenn er will.
Gast
#6240022
clang optimiert den Aufruf von foo in folgendem Beispiel weg.
Das Programm terminiert. Dagegen bleibt die while-Schleife in:
erhalten.
Gast
#6240024
Das waere ja gemogelt. Aber evtl taete es ein:
Keine Ahnung schrieb: > while (1) > äquivalent zu? > void FunktionA (void) > void FunktionB (void) > > void FunktionA() > { > FunktionB(); > } > > void FunktionB() > { > FunktionA(); > } Ist dieses Beispiel hier der Prototyp der neuzeitlichen Fragekultur, bei dem noch implizit erwartet wird, daß die Leser mehr schreiben sollen als der Fragesteller und sich noch die Kür einer kompetenten Antwort geben sollen? mfG Bei vielen modernen Compilern wird das bei aktivierter Optimierung tatsächlich äquivalent sein. Es gibt da die Tail call optimization (keine Ahnung wie das auf Deutsch heißt). Ist der letzte Befehl einer Funktion ein Funktionsaufruf wird aus Aus:
einfach
Das spart einen Sprung am Funktionsende und reduziert den maximalen Stackverbrauch. Daher würden im obigen Beispiel die Funktionsaufrufe vermutlich als Sprünge umgesetzt. Und damit ist es äquivalent zum while(1); Hermann K. schrieb: > Bei vielen modernen Compilern wird das bei aktivierter Optimierung > tatsächlich äquivalent sein. Es gibt da die Tail call optimization > (keine Ahnung wie das auf Deutsch heißt). Nicht nur das. Bei mir macht gcc sämtliche Aufrufe komplett weg und ersetzt das ganze durch ein simples: [Code] .L7: jmp .L7 [/C] mh schrieb: > http://eel.is/c++draft/intro.progress Das ist ja mal eine bescheuerte Regel.
Gast
#6241030
Rolf M. schrieb: > Das ist ja mal eine bescheuerte Regel. Ich habe dann mal ein paar Fragen: - Warum ist die Regel bescheuert? - Glaubst du, das wurde in den Standard geschrieben, um Leute zu ärgern? - Kannst du ein gutes Beispiel geben, wo die Regel wirklich stört? mh schrieb: > Rolf M. schrieb: >> Das ist ja mal eine bescheuerte Regel. > Ich habe dann mal ein paar Fragen: > - Warum ist die Regel bescheuert? Weil ich keinen Sinn darin erkennen kann. > - Glaubst du, das wurde in den Standard geschrieben, um Leute zu ärgern? Nein, aber ich weiß auch nicht, welchem Zweck diese Regel dienen könnte. > - Kannst du ein gutes Beispiel geben, wo die Regel wirklich stört? Beispielsweise wenn man einen Scheduler für multithreading hat. Oft muss ja die überschüssige Rechenzeit irgendwo hin, also wenn kein Thread gerade irgendwas tun kann. Dafür gibt's den Idle-Thread, der aus einer einfachen Endlosschleife besteht. Oder ein Fehler-Handler für einen µC, wo man in einen kritischen Fehler läuft, dann vielleicht noch über einen Debug-Port Registerinhalte und sowas augegeben werden und das System danach in eine Endlosschleife läuft. Jetzt muss man quasi in solchen Fällen wegen dieser Regel eine dummy-Variable anlegen, die volatile ist und in jedem Durchlauf gelesen und verworfen wird, nur damit die Schleife gültig ist, oder wie soll das laufen? Und jetzt könntest du mir im Gegenzug ein Beispiel geben, wo diese Regel wirklich hilft. mh schrieb: > http://eel.is/c++draft/intro.progress > 3 During the execution of a thread of execution, each of the following > is termed an execution step: > (3.1) termination of the thread of execution, > (3.2) performing an access through a volatile glvalue, or > (3.3) completion of a call to a library I/O function, a synchronization > operation, or an atomic operation. > und5 [ Note: Because of this and the preceding requirement regarding > what threads of execution have to perform eventually, it follows that no > thread of execution can execute forever without an execution step > occurring. — end note ] Ok. Aber daraus abzuleiten, daß while(1){} in C++ nicht erlaubt sein, halte ich für sehr gewagt. Der Abschnitt vor deinem Zitat lautet (andere Nummerierung, da anscheinend anderer draft):
Den letzte Satz lese ich so, daß eine leere Endlosschleife wegoptimiert werden darf, aber nicht, daß die genrell verboten sei. Oliver
Gast
#6241176
Rolf M. schrieb: >> - Warum ist die Regel bescheuert? > > Weil ich keinen Sinn darin erkennen kann. > >> - Glaubst du, das wurde in den Standard geschrieben, um Leute zu ärgern? > > Nein, aber ich weiß auch nicht, welchem Zweck diese Regel dienen könnte. Weil du keinen Sinn in der Regel erkennen kannst, ist die Regel bescheuert? Was soll man dagegen sagen? Ich versuche es mal direkt: Ich gehe erstmal davon aus, dass es einen sehr guten Grund gibt für diese Regel. Das ist im Allgemeinen ein gutes Vorgehen, wenn man keine Ahnung hat. Ist nicht böse gemeint, aber du hast bewiesen, dass du von diesem speziellen Thema keine Ahnung hast (du kanntest die Regel nicht, du hast kein Argument außer "dann muss ich Dinge anders lösen"). Rolf M. schrieb: > Und jetzt könntest du mir im Gegenzug ein Beispiel geben, wo diese Regel > wirklich hilft. Kann ich nicht, ich habe noch nie eine Endlosschleife gebraucht, aber ich freue mich immer, wenn der Compiler optimiert. Im Standard selbst steht z.B.
also gibt es vermutlich Leute, denen diese Optimierung wichtig ist. Dann kommt recht häufig "forward progress guarantee" und "lock-free execution" vor. Also wird es vermutlich Leute geben, die diese Garantie brauchen. Das ist gut genug für mich. Zu deinen Beispielen: -Dein Idle-Thread ist mir etwas suspekt. Es gibt keine Möglichkeit mit diesem Thread zu interagieren (pausieren, stoppen)? Ist das ein regulärer Thread oder genießt er eine Sonderbehandlung? Was passiert wenn die Rechenleistung gebraucht wird? -Der Fehlerhandler könnte auch einfach das "Programm" terminieren. Oliver S. schrieb: > Aber daraus abzuleiten, daß while(1){} in C++ nicht erlaubt sein, halte > ich für sehr gewagt. Ich gebe zu, die Formulierung "verboten" ist etwas zu stark. Aber viel Platz für Interpretation lässt der von mir zitierte Teil nicht:
Ich habe den "Was darf das Programm" Teil zitiert. Du hast den "Was darf der Compiler" Teil zitiert. Naja, so ganz dem Prinzip der geringsten Überraschung https://de.wikipedia.org/wiki/Principle_of_Least_Surprise entspricht die Wegoptimierung von endlosen Leerschleifen ja nicht gerade, aber noch viel weniger das, was Clang/LLVM in einigen Fällen daraus machen zu müssen meint. Beispiel:
Für -O0 entspricht das Verhalten noch voll den Erwartungen, aber mit höheren Optimierungsstufen sieht die Ausgabe so aus:
(Clang 10.0.0 unter Linux) Möglicherweise ist das ein Bug, vielleicht aber auch eine logische Konsequenz dieser komischen Optimierungsregel. mh schrieb: > http://eel.is/c++draft/intro.progress Das scheint nicht dem C++20-Draft zu entstammen, sondern wohl weiter in die Zukunft zu blicken. Vielleicht werde diese Dinge ja noch geändert. Wobei es diesen Unfug in C ja schon seit C11 gibt, allerdings mit einem entscheidenden Unterschied: Schleifen, deren Abbruchbedingung ein konstanter Ausdruck ist (wo der Compiler also leicht entscheiden kann, ob die Schleife terminiert oder nicht), werden ganz klassisch gehandhabt. Die von Rolf genannten Beispiele sind in C also nach wie vor realisierbar, wenn man die Endlosschleife als
o.ä. schreibt. Nur mit Clang/LLVM geeht das nicht, denn da wird die Regel auch für C angewandt, was aber wohl tatsächlich ein Bug ist.
Gast
#6241309
Yalu X. schrieb: > Das scheint nicht dem C++20-Draft zu entstammen, sondern wohl weiter in > die Zukunft zu blicken. Vielleicht werde diese Dinge ja noch geändert. Das müsste der 20er Draft Stand 2020-04-09 sein. Müsste ähnlich auch schon in C++11 gewesen sein. Yalu X. schrieb: > Wobei es diesen Unfug in C ja schon seit C11 gibt, allerdings mit einem > entscheidenden Unterschied: Schleifen, deren Abbruchbedingung ein > konstanter Ausdruck ist (wo der Compiler also leicht entscheiden kann, > ob die Schleife terminiert oder nicht), werden ganz klassisch > gehandhabt. Ja in C gibt es eine explizite Ausnahme für Schleifen mit konstantem Ausdruck als Abbruchbedingung. Ansonsten sind auch da Endlosschleifen mit nicht konstanter Bedingung Freiwild.
Gast
#6241320
Yalu X. schrieb: > Das scheint nicht dem C++20-Draft zu entstammen, sondern wohl weiter in > die Zukunft zu blicken. Ich wills nicht hoffen. Bisher ist mit AVR gcc 9.2 und -std=gnu++2a -Os eine Endlosschleife noch eine Endlosschleife. (werde es im Auge behalten) Yalu X. schrieb: > Das scheint nicht dem C++20-Draft zu entstammen, sondern wohl weiter in > die Zukunft zu blicken. Vielleicht werde diese Dinge ja noch geändert. Das steht im letzten C++17 Draft (als Kapitel 4.7), und damit vermutlich auch im C++17-Standard. Oliver
Gast
#6241498
Rekursion ist doch was feines... endlosschleifen auch.. warum also nicht.. wie wär's hiermit:
und nu nurmal so aus Spass.. was einfaches.. ack(4,3) zB.. ich denke das darf man dann auch als Endlossschleife bezeichen :D Mahlzeit 'sid
Gast
#6241616
sid schrieb: > warum also nicht.. sid schrieb: > was einfaches.. ack(4,3) zB.. Weil es undefined behaviour ist (signed integer overflow). Alternativ kannst du mir die Bitbreite des integer Datentyps angeben, mit dem es funktioniert.
Gast
#6241838
Yalu X. schrieb: > while(1); > for(;;); > Nur mit Clang/LLVM geeht das nicht Das ist aber eine sehr unangenehme Überraschung. Aber den von Dir geschilderten Segmentation fault kann wohl niemand mir gesunder Logik für gewollt halten, oder? mh schrieb: > Weil du keinen Sinn in der Regel erkennen kannst, ist die Regel > bescheuert? Was soll man dagegen sagen? Ich versuche es mal direkt: > Ich gehe erstmal davon aus, dass es einen sehr guten Grund gibt für > diese Regel. Das ist im Allgemeinen ein gutes Vorgehen, wenn man keine > Ahnung hat. Ist nicht böse gemeint, aber du hast bewiesen, dass du von > diesem speziellen Thema keine Ahnung hast (du kanntest die Regel > nicht, du hast kein Argument außer "dann muss ich Dinge anders lösen"). Du hast aber offenbar genauso wenig Ahnung, weil du auch nicht weißt, wozu diese Regel dienen soll. Du freust dich aber trotzdem darüber, weil du denkst, dass sie ja irgendwie gut sein muss. Ich seh's halt einfach etwas kritischer, auch wenn "bescheuert" zugegebenermaßen nicht die beste Wortwahl war. > Rolf M. schrieb: >> Und jetzt könntest du mir im Gegenzug ein Beispiel geben, wo diese Regel >> wirklich hilft. > > Kann ich nicht, ich habe noch nie eine Endlosschleife gebraucht, aber > ich freue mich immer, wenn der Compiler optimiert. Ich freue mich, wenn er sinnvoll optimiert. > Im Standard selbst steht z.B.[ Note: This is intended to allow compiler > transformations such as removal of empty loops, even when termination cannot > be proven. > — end note ] > also gibt es vermutlich Leute, denen diese Optimierung wichtig ist. Das kann ich mir für Schleifen, die nicht endlos sind, durchaus gut vorstellen. Aber solche Optimierungen waren auch schon vor dieser Regel erlaubt - nur eben nicht für Endlosschleifen. > Dann kommt recht häufig "forward progress guarantee" und "lock-free > execution" vor. Also wird es vermutlich Leute geben, die diese Garantie > brauchen. Das ist gut genug für mich. Für mich eben nicht. > Zu deinen Beispielen: > -Dein Idle-Thread ist mir etwas suspekt. Es gibt keine Möglichkeit mit > diesem Thread zu interagieren (pausieren, stoppen)? Der darf niemals pausiert oder gestoppt werden. Das ist ja gerade der Sinn des Idle-Threads. Er dient als "Auffangbecken" für gerade nicht benötigte Rechenzeit. Wenn der gestoppt wird, was soll der Prozessor dann tun, wenn alle anderen Threads gerade blockiert sind? Das ist übrigens nicht auf meinem Mist gewachsen, sondern ein ziemlich grundlegendes Element so ziemlich jedes mir bekannten Multitasking-Systems. Auch Windows hat den. Kann man im Taskmanager als "Leerlaufprozess" sehen. Wobei der in dem Fall etwas mehr macht als eine Endlosschleife, nämlich den Prozessor schlafen legen. > Ist das ein regulärer Thread oder genießt er eine Sonderbehandlung? Was > passiert wenn die Rechenleistung gebraucht wird? Was soll dann passieren? Dann gibt's einen Taskwechsel zu dem Thread, der sie braucht. Der Idle-Thread hat natürlich die niedrigste Priorität, so dass er nur dann drankommt, wenn wirklich kein anderer gerade was zu tun hat. > -Der Fehlerhandler könnte auch einfach das "Programm" terminieren. Auf einem Rechner mit Betriebssystem ja. Aber was verstehst du auf einem µC unter "das Programm terminieren"? Und was denkst du, was der nach dem Terminieren macht? Stefan ⛄ F. schrieb: > Yalu X. schrieb: >> while(1); >> for(;;); >> Nur mit Clang/LLVM geeht das nicht > > Das ist aber eine sehr unangenehme Überraschung. Und deshalb finde ich es "bescheuert". :) > Aber den von Dir geschilderten Segmentation fault kann wohl niemand mir > gesunder Logik für gewollt halten, oder? Soweit ich das beurteilen kann, wäre es aber wohl konform zu der Regel. Der Threadstarter kriegt von mir 9 von 10 Troll-Punkte. So eine blöde aber effektive Frage. Er musste nicht mal nachfüttern.
Gast
#6241919
Rolf M. schrieb: > Du hast aber offenbar genauso wenig Ahnung, weil du auch nicht weißt, > wozu diese Regel dienen soll. Du freust dich aber trotzdem darüber, weil > du denkst, dass sie ja irgendwie gut sein muss. Ich habe nie gesagt, dass ich besonders viel Ahnung habe, oder sogar ein Experte bin. Ich kannte die Regel aber immerhin. Und warum sollte ich mich nicht darüber freuen wenn der Standard Wert darauf legt, dass Optimierungen möglich sind? Was soll ich gegen diese Regel haben, wenn ich in ~15 Jahren c++ noch keine Endlosschleife benötigt habe? Rolf M. schrieb: > Für mich eben nicht. Du benötigst für alles was im Standard steht eine Begründung, die deinen Ansprüchen genügt? Viel Spass beim warten. Rolf M. schrieb: > Der darf niemals pausiert oder gestoppt werden. Das ist ja gerade der > Sinn des Idle-Threads. Mir ist klar, was ein Idle-Thread ist. Ich sehe nur nicht so ganz wie dieses Konzept in c++ funktionieren soll, ohne den Standard zu verlassen (zusätzlich zu Endlosschleifen). Rolf M. schrieb: > Auf einem Rechner mit Betriebssystem ja. Aber was verstehst du auf einem > µC unter "das Programm terminieren"? Und was denkst du, was der nach dem > Terminieren macht? In eine Endlosschleife laufen. Der Compiler/stdlib, darf sie benutzen. mh schrieb: > In eine Endlosschleife laufen. Womit wir wieder beim Problem wären...
Gast
#6241957
mh schrieb: > wenn > ich in ~15 Jahren c++ noch keine Endlosschleife benötigt habe? Hmmm... Wenn mich nicht alles täuscht, dann kann man schon soweit gehen, und sagen, dass jedes Programm, jeder Prozess, jeder Thread, eine Endlosschleife benötigt. Egal wie fett der Prozessor ist, egal welches OS. Von Win über Linux, und auch FreeRtos. OK, das "jeder" ist evtl. ganz leicht übertrieben. Ein paar Sonderfälle kann man da evtl. abziehen. Aber das bestätigt nur die Regel. Ob es immer die Kurzform > while(1); > for(;;); sein muss, ist eine andere Frage. Aber Endlosschleifen, die finden sich wie Sand am Meer. Oftmals, ohne jede Alternative. Ich glaube, ich hab's jetzt verstanden, musste aber ziemlich lange nach der Erklärung suchen. 1. Die Formulierung "may assume, that <x>" bedeutet: Ist <x> nicht erfüllt, ist das undefined Behavior. Damit ist u.a. auch
undefined Behavior, und "mh" hat recht gehabt mit seiner Behauptung,
dass solche Schleifen verboten sind. Damit ist der Crash in meinem
obigen Beispiel zwar zunächst überraschend, aber dennoch in Ordnung.
2. Bei dieser Regel geht es nicht etwa darum, leere Endlosschleifen
wegzuoptimieren (was ziemlich unsinnig wäre), sondern um solche
durchaus sinnvollen und auch gewünschten Optimierungen:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1528.htm
Somit hat das Ganze durchaus einen Sinn. Leider wissen offensichtlich
nur wenige davon, obwohl es diese Regel schon seit C++11 gibt (als ich
oben schrieb, das müsse etwas Neues sein, habe ich mich getäuscht).
Ich frage mich gerade, welche neueren C++-Lehrbücher auf diesen durchaus
wichtigen Punkt hinweisen. In den Büchern, die ich bisher gelesen habe,
ist mir so etwas nicht aufgefallen.
Wenn man in C++ tatsächlich eine Endlosschleife ohne einen erkennbaren
Effekt braucht, kann man das bspw. so machen:
In standardkonformen C reicht schon
Arduino Fanboy D. schrieb: > Wenn mich nicht alles täuscht, dann kann man schon soweit gehen, und > sagen, dass jedes Programm, jeder Prozess, jeder Thread, eine > Endlosschleife benötigt. Endlosschleifen an sich sind ja erlaubt. Verboten sind nur solche, die keinen Effekt haben (Nichtterminierung zählt in diesem Zusammenhang nicht als Effekt). Udo S. schrieb: > Der Threadstarter kriegt von mir 9 von 10 Troll-Punkte. > So eine blöde aber effektive Frage. > Er musste nicht mal nachfüttern. Da ich heute etwas wirklich Interessantes dazugelernt habe, gebe ich dem TE ein +1, was ich sonst praktisch nie tue. Ach ja, "mh" bekommt natürlich ebenfalls ein +1 für mh schrieb: > while(1){} > ist in c++ nicht erlaubt. Das war's dann für heute aber auch mit dem +1-Regen :)
Gast
#6241995
Ja, nee.... Der Kollege sagte: > wenn > ich in ~15 Jahren c++ noch keine Endlosschleife benötigt habe? DAS habe ich in Zweifel gezogen. Yalu X. schrieb: > Verboten sind nur solche, die > keinen Effekt haben Dass mir DAS nicht schmeckt, ist ein ganz anderes paar Schuhe. Denn ich habe einige Programme im Feld, welche genau diese leere Schleife verwenden. Manche, wo es als halt() eingesetzt wird, aus dem nur ein Reset die Erlösung bringt, und einige, welche eigentlich nur im Interrupt laufen, und die Schleife dazu dient, ungenutzte Zeit zu vertrödeln. Yalu X. schrieb: > for(;;) { > volatile char x; > (void)x; > } Schmeckt mir auch nicht sonderlich gut. Yalu X. schrieb: > ich heute etwas wirklich Interessantes dazugelernt habe, Ich auch. Mal schauen, wann es mir erstmalig auf die Füße fällt. mh schrieb: > Rolf M. schrieb: >> Für mich eben nicht. > Du benötigst für alles was im Standard steht eine Begründung, die deinen > Ansprüchen genügt? Viel Spass beim warten. Nicht für alles, aber ich befinde umgekehrt auch nicht alles automatisch für gut, nur weil's halt da drin steht.
Gast
#6242016
mh schrieb: > Weil es undefined behaviour ist (signed integer overflow). Alternativ > kannst du mir die Bitbreite des integer Datentyps angeben, mit dem es > funktioniert. 'tschuldigung, ich habe die Ackermannfunktion als bekannt vorausgesetzt und deswegen den Sarkasmus-tag nicht benutzt. bitbreite.. weiss nicht,dürfte so um 2^(2^65536) sein oder so; ich ging also davon aus, dass der overflow das geringste aller Probleme sein dürfte, da sie eh erst Wochen nach dem Wärmetod des Universums terminiert ;) und sind wir ehrlich dann ist die korrekte Antwort darauf auch egal :D Mahlzeit 'sid
Gast
#6242029
Arduino Fanboy D. schrieb: > Denn ich habe einige Programme im Feld, welche genau diese leere > Schleife verwenden. > Manche, wo es als halt() eingesetzt wird, aus dem nur ein Reset die > Erlösung bringt, und einige, welche eigentlich nur im Interrupt laufen, > und die Schleife dazu dient, ungenutzte Zeit zu vertrödeln. ja.. "Arduino Fanboy" gibt auch Auskunft darüber wo diese Programme dan eingesetzt werden nehm ich an ;) klar braucht man in microControllern schonmal ein "Ende" Das Problem liegt aber daran dass dein Code generell IMMER in einer Endlosschleife läuft (void loop()) und du dessen Ausführung blockieren willst, es aber aus besagter loop funktion kein return gibt soweit ich weiss. Ausserhalb von µCs allerdings sind solche Schleifen eher unerwünscht (vorsichtig formuliert) und man will sie um jeden Preis vermeiden, damit das Programm auch eine Rückgabe erzeugt mindestens eine Fehlermeldung. Also Äpfel und Birnen, ihr redet klar aneinander vorbei... 'sid
Gast
#6242039
Arduino Fanboy D. schrieb: > mh schrieb: >> wenn >> ich in ~15 Jahren c++ noch keine Endlosschleife benötigt habe? > > Hmmm... > > Wenn mich nicht alles täuscht, dann kann man schon soweit gehen, und > sagen, dass jedes Programm, jeder Prozess, jeder Thread, eine > Endlosschleife benötigt. Und "jedes Programm, jeder Prozess, jeder Thread" benötigt vermutlich einen Kontextwechsel. Jetzt rate mal wieviele ich davon standardkonform in C++ geschrieben habe? S. R. schrieb: > mh schrieb: >> In eine Endlosschleife laufen. > > Womit wir wieder beim Problem wären... Hättest du den zweiten Satz gelsen... mh schrieb: > In eine Endlosschleife laufen. Der Compiler/stdlib, darf sie benutzen. Rolf M. schrieb: > Nicht für alles, aber ich befinde umgekehrt auch nicht alles automatisch > für gut, nur weil's halt da drin steht. Aber von mir verlangst du, dass ich die genauen Gründe für diese Regel kenne. Sonst darf ich mich nicht freuen, dass der Standard Regeln einführt, die den Compilern bessere Möglichkeiten zum Optimieren gibt. sid schrieb: > 'tschuldigung, ich habe die Ackermannfunktion als bekannt vorausgesetzt > und deswegen den Sarkasmus-tag nicht benutzt. Ich kenne die Ackermannfunktion, kann in dem Post trotzdem keinen Sarkasmus erkennen. sid schrieb: > da sie eh erst Wochen nach dem Wärmetod des Universums terminiert ;) > und sind wir ehrlich dann ist die korrekte Antwort darauf auch egal :D Das kommt ganz aufs System an. Ich bin in weniger als 1 Sekunde in den a=0 b=Overflow gerannt für ack(4,3).
Gast
#6242083
Yalu X. schrieb: > aber mit > höheren Optimierungsstufen sieht die Ausgabe so aus: > > begin > begin > Segmentation fault (core dumped) Wow, gerade auch mit clang 8.0.0-3~ubuntu16.04.1 versucht, mit Optionen "clang++-8 -O2 -std=c++14 -Wall -Wextra -pedantic". Selbes Ergebnis, und vor allem, keine Warnung!!! Mit clang 3.8 lief es noch. Also, normalerweise verstehe ich es ja, wenn wegen UB etwas anders/nicht läuft, normalerweise gibt es zumindest nen vernünftigen Grund dafür. Aber das hier, das geht gar ja wohl nicht! Ohne die geringste Warnung, trotz maximaler Warnhöhe, ein Programm, wegen einem Teil, wo niemand bestreiten würde, was es tun sollte, derart zu Zerreissen, also da hört mein Verständnis für sowas dann doch mal langsam auf. Weiss jemand, wer dafür verantwortlich ist? Yalu X. schrieb: > Da ich heute etwas wirklich Interessantes dazugelernt habe, gebe ich dem > TE ein +1, was ich sonst praktisch nie tue. > > Ach ja, "mh" bekommt natürlich ebenfalls ein +1 für Hmm, das ist ein Beweis dass auch aus Trollversuchen noch was Gutes entstehen kann. :-) Aber das war ziemlich sicher ein unbeabsichtigter Effekt des TOs. DPA schrieb: > Wow, gerade auch mit clang 8.0.0-3~ubuntu16.04.1 versucht, mit Optionen > "clang++-8 -O2 -std=c++14 -Wall -Wextra -pedantic". Selbes Ergebnis Der Crash entsteht dadurch, dass das kompilierte main() am Ende kein RET bzw. RETQ hat. Für mich sieht es so aus, als ob der Compiler bzgl. der Endlosschleife etwas zwiegespalten ist: Sein erste Gedankengang: "foo() enthält ja eine Endlosschleife, also ist in main() alles nach dem Aufruf von foo() (einschließlich der impliziten return-Anweisung) unreachable Code, der wegoptimiert werden kann." Dann sagt er sich: "Die Schleife in foo() hat ja überhaupt keinen Effekt (im Sinne des Standards), also muss sie laut Standard terminieren. Wenn sie aber nichts tut und terminiert, kann sie ebenfalls wegoptimiert werden." Der erste Schritt beruht also darauf, dass die Schleife endlos ist, der zweite auf dem Schluss, dass die Schleife gar nicht endlos sein kann, was eigentlich einen Widerspruch darstellt. Zurück bleibt schließlich ein verstümmeltes main(), das bei der Ausführung ins Nirwana läuft. Da bei undefined Behavior der Compiler für nichts zu garantieren braucht, ist das rein formal auch völlig in Ordnung. Schuld ist der Programmierer (in diesem Fall also ich ;-)). > und vor allem, keine Warnung!!! Ja eine Warnung hätte ich mir hier auch erhofft. Auf Grund des oben erwähnten Widerspruchs sollte sofort klar sein, dass mit dem Code etwas nicht stimmt. Ich vermute aber, dass sich die beiden Gedankengänge in verschiedenen Optimierungsmodulen des Compilers abspielen, die nicht miteinander kommunizieren, weswegen dieser Widerspruch unentdeckt bleibt und somit auch keine Warnung ausgegeben werden kann.
Gast
#6242342
mh schrieb: >> da sie eh erst Wochen nach dem Wärmetod des Universums terminiert ;) >> und sind wir ehrlich dann ist die korrekte Antwort darauf auch egal :D > Das kommt ganz aufs System an. Ich bin in weniger als 1 Sekunde in den > a=0 b=Overflow gerannt für ack(4,3). ne kommt nicht auf das System an, Du hast nicht ausreichend bits in deinem Computer um es auch nur zu versuchen.. es benötigt weit mehr bits als Protonen im bekannten Universum ganz zu schweigen dass der Aufrufstack dir selbst irgendwann in den Nacken schlägt. mh schrieb: > Ich kenne die Ackermannfunktion, kann in dem Post trotzdem keinen > Sarkasmus erkennen. scheinbar kennst Du sie nicht. Denn dann würdest Du es garnicht erst probieren laufen zu lassen.. selbstredend rennst Du zuerst in nen Overflow; völlig egal wie Also ist die Frage nach der bitzahl schon völlig Hirnlos in diesem Zusammenhang. Und der unumstössliche Beweis, dass Du sie nicht kennst. (oder ihre grauenhafte Art jmd in die Falle tappen zu lassen) da die Funktionsparameter kontinuierlich fallend aussehen und nur der Rückgabewert in Einzelschritten incrementiert, scheint sie harmlos, tritt einem aber gehörigst in den Allerwertesten bei nur kleinen Aufrufparametern (4,3) scheint ja überschaubar. Den Sarkasmus darin erkennt man in der Tat nur wenn man das vorher weiss. hättest Du sie erkannt hätte Dir schon https://de.wikipedia.org/wiki/Ackermannfunktion#Genauere_Betrachtung geholfen das gehässige an (4,3) zu sehen Zitat: ---- Wir betrachten nun einen komplexeren Fall, nämlich a ( 4 , 3 ) , den ersten Funktionswert, der so groß ist, dass er praktisch nicht dezimal aufgeschrieben werden kann. ... Wenn wir an dieser Stelle mehrere logische Schritte überspringen, könnten wir a ( 2 , 5 ) zu 13 auswerten und dann versuchen, a ( 3 , 13 ) auszuwerten – das ist 65533. Doch schon der nächste Funktionsaufruf liefert mit a ( 3 , 65533 ) eine Zahl, die weit über die geschätzte Anzahl der Atome im Universum hinausgeht. Diese Zahl m wird schließlich in die Berechnung a ( 3 , m ) eingesetzt, die irgendwann zu einem Ausdruck der Form a ( 2 , a ( 2 , a ( 2 , … , a ( 2 , 0 ) … ) ) ) ausgeschrieben würde, die aber mit unseren Mitteln nicht mehr aufgeschrieben werden kann. ------------ Wie gesagt, ich habe zu unrecht erwartet dass man sie erkennt; mein Fehler.. aber dass Du jetzt so tust Du hättest sie erkannt und im selben Atemzug sagst Du hättest es dennoch probiert (und auch noch ein Ergebniss erwartet) dann zeigt das klar, dass Du lügst (oder es dir an Auffassunggabe und Zurechnungsfähigkeit mangelt) Sarkasmus nicht erkannt? sid schrieb: > Rekursion ist doch was feines... > .... > und nu nurmal so aus Spass.. was einfaches.. ack(4,3) zB.. > ich denke _das darf man dann auch als Endlossschleife bezeichen_ :D einfach..(HUST) "darf man als Endlosschleife bezeichnen" (ZAUNPFAHLWINK) Ja ggf nicht klar genug, deswegen meine obige Entschuldigung; aber bitte, tu jetzt nicht so als läge es an einer fehlenden Angabe der bitbreite, denn dir fehlt Kapazität auch nur die Anzahl der bits auszuschreiben und tu nicht so als sei die Berechnung eine Frage der Rechenkapazität; denn auch nur der Gedanke Du seist in der Lage ist völlig absurd. Lass Deinen Computer mal bis 2^512 hochzählen (in Einzelschritten) (stop die Zeit!) und dann überleg mal was 2^65536 ungefähr dauern könnte. und nun kommen wir zurück auf 2^(2^65536) ... Na?? merkste was? 2^65536 sind etwa 19729 dezimalziffern und das ist nur der exponent. 'sid Yalu X. schrieb: > Zurück bleibt schließlich ein verstümmeltes main(), das bei der > Ausführung ins Nirwana läuft. Da bei undefined Behavior der Compiler für > nichts zu garantieren braucht, ist das rein formal auch völlig in > Ordnung. Schuld ist der Programmierer (in diesem Fall also ich ;-)). Das nennt man dann eine "quality of implementation issue". Der Compiler macht zwar formal nichts falsch, aber seine Handhabung dieser Situation ist dennoch aus Anwendersicht eher unglücklich.
Gast
#6242563
sid schrieb: > ne kommt nicht auf das System an, > Du hast nicht ausreichend bits in deinem Computer um es auch nur zu > versuchen.. Natürlich kommt es aufs System an, wann man in den Overflow läuft. sid schrieb: > ganz zu schweigen dass der Aufrufstack dir selbst irgendwann in den > Nacken schlägt. Der Stack hat noch ordentlich Luft nach oben. sid schrieb: > scheinbar kennst Du sie nicht. > Denn dann würdest Du es garnicht erst probieren laufen zu lassen.. Ich darf also nicht testen, ob zuerst nen stack overflow oder signed integer overflow eintritt, und wann genau? sid schrieb: > Sarkasmus nicht erkannt? > > sid schrieb: >> Rekursion ist doch was feines... >> .... >> und nu nurmal so aus Spass.. was einfaches.. ack(4,3) zB.. >> ich denke das darf man dann auch als Endlossschleife bezeichen :D > > einfach..(HUST) "darf man als Endlosschleife bezeichnen" (ZAUNPFAHLWINK) Auch wenn du das Zitat abänderst ist das kein Sarkasmus, bestenfalls Ironie. Für den Fall, dass du irgendwann mit deinen Unterstellungen fertig bist und zu einer Diskussion bereit bist, fasse ich meinen Standpunkt nochmal zusammen, den ich mit dem Beitrag mh schrieb: > sid schrieb: >> warum also nicht.. > > sid schrieb: >> was einfaches.. ack(4,3) zB.. > > Weil es undefined behaviour ist (signed integer overflow). Alternativ > kannst du mir die Bitbreite des integer Datentyps angeben, mit dem es > funktioniert. darstellen wollte. Deine Funktion, mit den Werten a=4, b=3 aufgerufen, produziert einen signed integer overflow und ist nach Standard damit undefined behaviour. Wenn der Compiler das mitbekommt kann er machen was er will, z.B. nach 42 Sekunden (lange vor dem Wärmetod des Universums) den Wert 7353 zurückgeben. Die Bitbreite ist also der entscheidende Punkt. Und falls du es noch nicht gemerkt hast, deine Antwort sid schrieb: > bitbreite.. weiss nicht,dürfte so um 2^(2^65536) sein oder so; ist falsch (mehrere Größenordnungen). sid schrieb: > einfach..(HUST) "darf man als Endlosschleife > bezeichnen" (ZAUNPFAHLWINK) Das ist falsch, weil es sich eben nicht wie eine Endlosschleife verhält, auch nicht für reale Zeitverhältnisse.
Gast
#6242873
mh schrieb: > Auch wenn du das Zitat abänderst ist das kein Sarkasmus, bestenfalls > Ironie. Ohweh, Mathe nicht, Sprache nicht... naja dann; wie isset mit Religion? wiki schreibt: >Sarkasmus kann durch direkte Aussage des Gemeinten oder mittels Ironie ausgedrückt werden. Aber lassen wir das, nicht dass Du da in die nächste Selbstgeisselung rennst. mh schrieb: > Ich darf also nicht testen, ob zuerst nen stack overflow oder signed > integer overflow eintritt, und wann genau? ne, brauchste ja nicht.. weiss man ja wenn man die Funktion kennt.. hab ich dir ja sogar zitiert.. sobald die Funktion sich selbst mit (3,65533) aufruft rennst Du zwangsläufig in einen integer overflow.. EGAL BEI WELCHER BITBREITE! und der stack dürfte da noch an zehn Fingern abzuzählen sein. 'würde' das durchlaufen (was es nicht kann...) würde Dir im darauffolgenden Schritt der stack überlaufen.. genauso zwangsläufig wie der integer overflow auftritt, weil das Ergebniss dessen jene besagten 19729 Ziffern sind (2^65536) und genausooft würde die Funktion sich selbst verschachtelt aufrufen wollen ('tschüss stack!'); um dann das (ab sofort nurnoch fiktive) Ergebniss (in der Nähe von 2^2^65536) auszuspucken besagte Wochen nach dem Wärmetod des Universums, wenn der Stack dann wieder abzählbar ist. Wie gesagt, wenn man die Funktion kennt, weiss man das; man weiss auch dass der integer overflow IMMER exakt einen (fiktiven) Schritt auf selber stackebene vor dem unausweichlichen Stack Overflow kommt. Wie gesagt, Du bestätigst nur nochmals, dass Du die Funktion eben nicht kennst, mindestens aber Dir ihrer Gemeinheit nicht im Klaren bist; maximal glaub ich noch, dass Du mal von ihr gehört hast. Das ist ansich nichts schlimmes.. (muss man nicht wissen mMn) Aber ernsthaft, langsam wird es albern mit deinem sich rausreden wollen, Denn dann allerdings muss ich dir wirklich Ignoranz oder Dummeheit unterstellen, anders kann ich mir das nichtmehr erklären wieso man es überhaupt versucht unter der Prämisse die Funktion "zu kennen". Ich fürchte fast Du hast nichteinmal eine Ahnung wie gross die Zahlen sind, von denen Du da glaubst sie "berechnen" zu können, was Dich dann allerdings in wirklich schlechtes Licht tauchen würde. Sone ungefähre Ahnung von Grössenordnung sollte man schon haben 10^80 geschätzte Atome im Universum verglichen mit 2^65536 als EXPONENT macht einem recht einleuchtend klar (hoffentlich) dass jeder Versuch zwangläufig vollends NUTZLOS ist. S. R. schrieb: > Das ist falsch, weil es sich eben nicht wie eine Endlosschleife verhält, > auch nicht für reale Zeitverhältnisse. da es keine realen Zeitverhältnisse gibt nach dem Wärmetod des Universums ist der Einwand eher zu vernachlässigen. Die Funktion KANN sich real nicht "korrekt" verhalten mit den Aufrufparametern (4,3), eben WEIL sie die Ackermannfunktion ist und egal welcher Computer sich eben mit begrenzten Ressourcen zufriedengeben muss. Mit kleineren Aufrufparametern kann sie sich nicht wie eine "Endlossschleife" verhalten, weil man eben nur ein Ergebniss zurückbekommt, und zwar in sehr realen und überschaubaren "Zeitverhältnissen" Aber jaja.. ich hab verstanden, ich bin der Einzige der das lustig fand zu dieser -da müsst ihr aber zustimmen- ziemlich bekloppten Fragestellung. 'sid
Gast
#6242986
sid schrieb: > Sarkasmus nicht erkannt? sid schrieb: > Aber jaja.. ich hab verstanden, > ich bin der Einzige der das lustig fand Was soll man dazu sagen? sid schrieb: > Sarkasmus kann durch direkte Aussage des Gemeinten oder mittels Ironie > ausgedrückt werden. Falls du es noch nicht weißt, nicht immer ist das "direkte Aussagen des Gemeinten" Sarkasmus. Es gibt noch andere Bedingungen ;-) sid schrieb: > Aber jaja.. ich hab verstanden, > ich bin der Einzige der das lustig fand zu dieser -da müsst ihr aber > zustimmen- ziemlich bekloppten Fragestellung. Nein, ich musste da auch innerlich grinsen. Die Erinnerung an die Ackermann-Funktion war zwar nur dürftig, aber an die Bösartigkeit bzgl. Wertebereich und Rekursionstiefe konnte ich mich doch noch erinnern. Aber wenigstens hat die nachfolgende Diskussion mich dazu gebracht, das mal tiefer nachzulesen als ich mir das damals (vor einigen Jahrzehnten, bin halt ein alter Sack ;-) ) im Informatik-Studium angetan habe. Jetzt kenne ich auch Tetration und Hyperoperatoren. Danke. :-) Yalu X. schrieb: > Für mich sieht es so aus, als ob der Compiler bzgl. der Endlosschleife > etwas zwiegespalten ist Das sehe ich auch so. Müsste man mal einen Blick in die LLVM-IR werfen und das mit dem Assembler-Listing vergleichen. Das sollte etwas mehr Aufschluss geben.
Gast
#6243164
Rolf M. schrieb: >> - Warum ist die Regel bescheuert? > > Weil ich keinen Sinn darin erkennen kann. Ah ja. Das ist der Standpunkt "was ICH nicht weiß, das gibt es auch nicht!" (oder "..darf es nicht geben!") Ich sehe das wieder mal etwas anders: Ein while(1) ist eigentlich eine Vergewaltigung einer bedingten Schleife, genauso wie es ein for(;;) ist. Bedingte Schleifen sind dafür da, eben BEDINGT zu sein und nicht zur unbedingten Schleife verhunzt zu werden. Also ist so etwas einfach nur ein schlechter Programmierstil und ich habe kein Problem damit, wenn eine Regel so etwas stigmatisiert. Und wenn man eine tatsächliche unbedingte Schleife haben will, dann setzt man ein Label und benutzt goto. Das wird ja wohl hoffentlich nicht mal vom GCC hinweg optimiert. Und Label + goto ergeben die klassische unbedingte Schleife. W.S. W.S. schrieb: > Ah ja. Das ist der Standpunkt "was ICH nicht weiß, das gibt es auch > nicht!" (oder "..darf es nicht geben!") Nein: Der Standpunkt ist: "was ich nicht für sinnvoll erachte, das muss ich auch nicht gut finden." > Ich sehe das wieder mal etwas anders: > > Ein while(1) ist eigentlich eine Vergewaltigung einer bedingten > Schleife, genauso wie es ein for(;;) ist. Bei while(1) gebe ich dir recht, da man als "Bedingung" etwas einträgt, das immer wahr ist und somit das Konzept der bedingten Wiederholung eigentlich ad absurdum geführt wird. Das finde ich jetzt zwar nicht so kritisch (wenn nicht irgendwelche merkwürdigen Regeln plötzlich dafür sorgen, dass das nicht mehr so funktioniert, wie man eigentlich erwarten würde), aber doch unschön. Bei for aber wurde explizit die Möglichkeit vorgesehen, eine Bedingung gar nicht angeben zu müssen und damit eine Schleife ohne Bedingung zu erzeugen. Genau das macht dein for(;;) ja auch. Da wird also nichts "vergewaltigt", sondern ein Sprachfeature genau für das genutzt, wofür es gedacht ist. > Und wenn man eine tatsächliche unbedingte Schleife haben will, dann > setzt man ein Label und benutzt goto. Das wird ja wohl hoffentlich > nicht mal vom GCC hinweg optimiert. Und Label + goto ergeben die > klassische unbedingte Schleife. Das ist deine Alternative? Label+goto? Naja, begeistert mich nicht sehr. Im Übrigen fällt auch das unter die hier diskutierte Regel. Die ist völlig unabhängig davon, auf welchem Weg man die Endlosschleife baut.
Gast
#6243282
W.S. schrieb: > Und Label + goto ergeben die > klassische unbedingte Schleife. Womit man dann erst am Ende weiß das es eine Endlosschleife ist und auch das nur vielleicht. Weil wer goto nimmt springt dann auch per goto zum erroerhandler. Proggst du in Assembler? Da macht das evtl. Sinn. Der Compiler macht aus while(1) das gleiche wie aus for... und goto. Der goto man verliert aber die Programmstruktur und darf sich zum Ende durchwühlen wenn er daraus ne Funktion machen will.
Gast
#6243300
Rolf M. schrieb: > Bei while(1) gebe ich dir recht, da man als "Bedingung" etwas einträgt, > das immer wahr ist und somit das Konzept der bedingten Wiederholung > eigentlich ad absurdum geführt wird. Warum? Die Bedingung ist halt immer wahr. Wenn 21. Juni dann Sommersonnenwende ist auch immer wahr. Nur halt nicht jeden Tag. Man macht das wg. konsistenter Programmstrukturen und ein goto ist da so fehl am Platze wie while(4 != Pi()) was ja ne "echte" Bedingung mit dem gleichen Ergebnis wäre. Toby P. schrieb: > Rolf M. schrieb: >> Bei while(1) gebe ich dir recht, da man als "Bedingung" etwas einträgt, >> das immer wahr ist und somit das Konzept der bedingten Wiederholung >> eigentlich ad absurdum geführt wird. > > Warum? Wenn ich eine Schleife ohne Bedingung will, möchte ich das möglichst auch so hinschreiben können und nicht stattdessen als bedingte Schleife mit einer Bedingung, die sich nie ändert. Einfach weil es eine präzisere und direktere Beschreibung meiner Absicht ist. Wie gesagt: Ich finde ein while(1) nicht furchtbar, aber eben weniger schön als eine Möglichkeit, eine unbedingte Schleife auch ohne Bedingung zu formulieren. Deshalb bevorzuge ich for(;;). > Man macht das wg. konsistenter Programmstrukturen und ein goto ist da so > fehl am Platze wie while(4 != Pi()) was ja ne "echte" Bedingung mit dem > gleichen Ergebnis wäre. Dass ich goto da auch nicht für eine gute Idee halte, hab ich ja schon geschrieben.
Gast
#6243416
Rolf M. schrieb: > Einfach weil es eine präzisere > und direktere Beschreibung meiner Absicht ist Naja.. Man kann "Absicht" auf verschiedene Art ausdrücken. Toby P. schrieb: > Der goto man verliert aber die Programmstruktur und darf sich zum Ende > durchwühlen wenn er daraus ne Funktion machen will. Bin mittlerweile voll auf Goto! Klarer: Listig eingesetzte Goto können die Absicht auch verdeutlichen! Und gleichzeitig helfen die Komplexität zu verbergen. Im Anhang mal ein Beispiel, wie das(manchmal) in meiner kleinen (hauptsächlich AVR) Arduino Welt aussieht. OK, das ist kein SpeicherSparWunder, aber es drückt die "Absicht" recht klar aus, auch wenn das goto schön versteckt ist, und einige Endlosschleifen da rum dümpeln --- Goto hat seinen schlechten Ruf aus vergangen Zeiten, und mit anderen Sprachen, als C oder C++, erworben. Sicherlich kann man mit Goto auch derbe Mist bauen! Aber das gilt wohl auch für alle anderen Sprachmittel. PS: Die Library habe ich nicht dazu gepackt. 1. interessiert vermutlich sowieso keinen hier 2. ist (noch) nicht gefegt und poliert W.S. schrieb: > Ein while(1) ist eigentlich eine Vergewaltigung einer bedingten > Schleife, genauso wie es ein for(;;) ist. Bedingte Schleifen sind dafür > da, eben BEDINGT zu sein und nicht zur unbedingten Schleife verhunzt zu > werden. > > Also ist so etwas einfach nur ein schlechter Programmierstil und ich > habe kein Problem damit, wenn eine Regel so etwas stigmatisiert. > > Und wenn man eine tatsächliche unbedingte Schleife haben will, dann > setzt man ein Label und benutzt goto. Das wird ja wohl hoffentlich > nicht mal vom GCC hinweg optimiert. Und Label + goto ergeben die > klassische unbedingte Schleife. Immerwieder geil, dass du jedem hier im Forum Beweisen musst, dass du nicht programmieren kannst. goto statt while(1), das wird morgen für Gelächter in der Teambesprechung sorgen zur Auflockerung. Toby P. schrieb: > Man macht das wg. konsistenter Programmstrukturen und ein goto ist da so > fehl am Platze wie while(4 != Pi()) was ja ne "echte" Bedingung mit dem > gleichen Ergebnis wäre. Ähh, der Wert von Pi ist teilweise regional unterschiedlich. Je nachdem, ob der Wert irgendwann auf 3,2 oder 4 festgelegt wird, wäre die o.a. Bedingung also wahr oder falsch. Man beachte, dass das Gesetzgebungsverfahren nur unterbrochen, aber niemals beendet wurde: https://de.wikipedia.org/wiki/Indiana_Pi_Bill sid schrieb: >> Das ist falsch, weil es sich eben nicht wie eine >> Endlosschleife verhält, auch nicht für reale Zeitverhältnisse. > > da es keine realen Zeitverhältnisse gibt nach dem Wärmetod des > Universums ist der Einwand eher zu vernachlässigen. Du hast eine schlecht implementierte Ackermannfunktion als Ersatz für eine Endlosschleife vorgeschlagen. Die verhält sich aber auf realen Zeitspannen (z.B. innerhalb eines Monats) nicht wie eine Endlosschleife. Das Ende des Universums ist da irrelevant, weil der Code schon lange vorher scheitert. Tjoot.
Gast
#6243975
Meine Endlosschleife auf dem C64 (Commodore Basic V2):
Der begrenzten Genauigkeit wegen, kann der Endwert nie erreicht werden. Vorteil: Die literale Sprungadresse liegt wegen der for-Schleife auf dem for-next Stack und muss nicht aufwendig gesucht werden.
Gast
#6244013
Toby P. schrieb: > Der Compiler macht aus while(1) das gleiche wie aus for... und goto. Hast du hier nichts gelesen? Die ganze Diskussion ging darum, daß der GCC sowas wie while(1) einfach wegoptimiert. Er fährt also dem Programmierer einfach so über's Maul (!!!) - weil eben mal wieder irgend wer von den Compilerbauern den Sinn von etwas nicht hat einsehen wollen und gemäß der Direktive "was ich nicht einsehe, das darf nicht sein" sowas offenbar zum Wegoptimieren freigegeben hat. OK, ich selber benutze den GCC aus derartigen Gründen nicht, aber es erstaunt mich immer wieder, mit was für eigentümlichen Hakeleien die GCC-Benutzer sich herumschlagen müssen. Was also tun, wenn sowas wie while(1) nicht geht? Mir fällt (siehe oben) da nur das dedizierte GOTO marke ein, in der Hoffnung, daß die Compilerbauer nicht derart frech sind, dieses ebenfalls wegzuoptimieren. Muß man beim GCC mit der Brechstange programmieren? Wie schonmal gesagt: von einem Compiler erwarte ich, daß er das, was ich hingeschrieben habe, richtig und optimal in Maschinencode übersetzt - aber er hat nicht auf eigene Faust irgendwas zu unterschlagen - bloß weil irgendwer das nicht einsehen wollte. W.S.
Gast
#6244021
W.S. schrieb: > OK, ich selber benutze den GCC aus derartigen Gründen nicht, aber es > erstaunt mich immer wieder, mit was für eigentümlichen Hakeleien die > GCC-Benutzer sich herumschlagen müssen. Der gcc macht diese Optimierung gerade NICHT. Mal davon abgesehen, dass der Nutzer einen Fehler gemacht hat, wenn er den gcc zum Compilieren von C++ benutzt, dafür ist der g++ gedacht. W.S. schrieb: > Die ganze Diskussion ging darum, daß der > GCC sowas wie while(1) einfach wegoptimiert. Nö, der GCC tut das nicht. Clang tut es und der Standard erlaubt es auch. Und damit betrifft das auch dich, egal welchen Compiler du benutzt. W.S. schrieb: > Mir fällt (siehe oben) da nur das dedizierte > GOTO marke ein, in der Hoffnung, daß die > Compilerbauer nicht derart frech sind, > dieses ebenfalls wegzuoptimieren. Der Standard verbietet endlose, effektfreie Codesequenzen. Das betrifft damit auch dein "lbl: goto lbl;"
Beitrag #6244112 wurde von einem Moderator gelöscht.
mh schrieb: > Mal davon abgesehen, dass der Nutzer einen Fehler gemacht hat, wenn er > den gcc zum Compilieren von C++ benutzt, dafür ist der g++ gedacht. GCC ist die GNU Compiler Collection. Zu der gehört das C++-Frontend g++ und das allgemeine Frontend für alle unterstützten Sprachen gcc.
Gast
#6244155
Rolf M. schrieb: > GCC ist die GNU Compiler Collection. Dann ist es aber nicht "der/den GCC" ;-) Rolf M. schrieb: > Zu der gehört das C++-Frontend g++ und das allgemeine Frontend für alle unterstützten Sprachen gcc. Das ist mir bekannt. Mir ist aber auch bekannt, dass das unter anderem beim Linken einige Probleme machen kann (einfachster Fall stdlib von Hand dazulinken). Es gibt nen Grund warum es den g++ gibt und der gcc selbst
sagt. W.S. schrieb: > Er fährt also dem > Programmierer einfach so über's Maul (!!!) - weil eben mal wieder irgend > wer von den Compilerbauern den Sinn von etwas nicht hat einsehen wollen > und gemäß der Direktive "was ich nicht einsehe, das darf nicht sein" > sowas offenbar zum Wegoptimieren freigegeben hat. Es sind immer die selben Ammenmärchen die von dir kommen. Von allen Seiten wurdest du jetzt schon zig mal zu diesem Thema aufgeklärt. Deine Borniertheit und Starrsinnigkeit ist hier im Forum echt unübertroffen. W.S. schrieb: > OK, ich selber benutze den GCC aus derartigen Gründen nicht, aber es > erstaunt mich immer wieder, mit was für eigentümlichen Hakeleien die > GCC-Benutzer sich herumschlagen müssen. Ja, du benutzt den Keil, weil der ja sooo viel besser ist als der GCC aber soll ich dir mal ein Geheimnis verraten (was eigentlich gar nicht so geheim ist)? Der "Keil" nutzt in seinen aktuellen Versionen ("ARM Compiler Version 6") Clang/LLVM als Unterbau, also genau den Compiler mit den "eigentümlichen Hakeleien".
Gast
#6245581
Christopher J. schrieb: > Der "Keil" nutzt in seinen aktuellen Versionen Der geht mich nix an. Meine Lizenz ist schon ein paar Jährchen alt - und sie reicht aus für alles, was bei mir anfällt. W.S. Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|