for(;;){} Schleife

(Firma: Eigenbau) #7474420
Lesenswert?

Guten Tag, habe diese Schleife in einer älteren C-Firmware von Pic-Microchip gesehen und gerätselt:

for(;;) { if ((SWITCH_S2) && (!Flags.MotorRunning)) { while(SWITCH_S2); RunMotor(); // Run motor if push button is pressed and motor is // stopped } else if ((SWITCH_S2) && (Flags.MotorRunning)) { while(SWITCH_S2); StopMotor();// Stop motor if push button is pressed and motor is // running } }

Hat jemand schon eine solch eigenartige for-Schleife gesehen?

Moderator Persönliche Seite #7474456
Lesenswert?

Jan S. schrieb:

da hätte man doch gleich while(1) schreiben können

Bei "for (;;)" ist offensichtlich, dass der Autor das so wollte, das entsteht nicht mal irgendwo aus Versehen.

"while(1)" könnte beispielsweise aus einer Makroersetzung "while (IS_SOMETHING_GOING_ON())" kommen, deren Inhalt unbeabsichtigt zu "1" wurde, daher lässt man sowas den Compiler lieber warnen.

Folglich gibt es style guides, die "for (;;)" explizit für eine Endlosschleife vorschreiben.

#7474459
Lesenswert?

Hallo, Jan S. schrieb im Beitrag #7474436:

...da hätte man doch gleich while(1) schreiben können...

Im Buch "Code complete" von Steve McConnell wird für C empfohlen eine Endlosschleife mit einem Makro einzuleiten:

1
#define FOREVER   for(,,)
2
...
3
FOREVER
4
    {
5
    ...
6
    }

rhf

Gast #7474548
Lesenswert?

Bauform B. schrieb:

Jan S. schrieb:

Danke für die Antwort, da hätte man doch gleich while(1) schreiben können, hat mich etwas verwirrt...

for(;;) kann man als "forever" lesen, das finde ich schöner als

Lächerlich. Hinterlass lieber einen comment, der auch dem dümmsten Source-Code Leser klar macht, was hier gemeint ist.

Und wer sich nicht scheut, das "verpönte" goto in C einzusetzen könnte es auch schreiben wie es realisiert wird:

forever: goto forever;

https://www.javatpoint.com/infinite-loop-in-c https://stackoverflow.com/questions/20186809/endless-loop-in-c-c

Beitrag #7474667 wurde von einem Moderator gelöscht.
#7474900
Lesenswert?

Bruno V. schrieb:

for(;;) ist vorgesehen als Standard-Endlosschleife. While erfordert einen Ausdruck, während bei "for" das zweite Argument explizit optional ist

Ja, das ist für mich auch der Grund, warum ich for(;;) bevorzuge. Es gibt keine Bedingung für die Schleife, und bei /for/ kann ich das auch direkt so ausdrücken. Bei /while/ muss ich dagegen eine Pseudo-Bedingung hinschreiben.

#7474914
Lesenswert?

Rolf M. schrieb:

Bruno V. schrieb:

for(;;) ist vorgesehen als Standard-Endlosschleife. While erfordert einen Ausdruck, während bei "for" das zweite Argument explizit optional ist

Ja, das ist für mich auch der Grund, warum ich for(;;) bevorzuge. Es gibt keine Bedingung für die Schleife, und bei /for/ kann ich das auch direkt so ausdrücken.

Das ist doch an den Haaren herbei geholt!

Bei /while/ muss ich dagegen eine Pseudo-Bedingung hinschreiben.

Wieso Pseudo? Die Bedingung statt ganz klar als Literal "true" dort. Nix Pseudo.

Bei /for/ steht nichts, und man muss, falls man das Idiom nicht kennt, nachdenken. Bei /while/ steht es explizit da. Und explizit ist immer besser als implizit.

#7474947
Lesenswert?

Wilhelm M. schrieb:

Ja, das ist für mich auch der Grund, warum ich for(;;) bevorzuge. Es gibt keine Bedingung für die Schleife, und bei for kann ich das auch direkt so ausdrücken.

Das ist doch an den Haaren herbei geholt!

Warum? Ich will eine unbedingte Schleife, habe also keine Bedingung. Bei for kann ich diese weglassen und bekomme dann genau das, was ich will. Was ist daran "an den Haaren herbei geholt"? Das passt doch nun wirklich wie die sprichwörtliche Faust aufs Auge.

Wilhelm M. schrieb:

Bei while muss ich dagegen eine Pseudo-Bedingung hinschreiben.

Wieso Pseudo?

Weil eine 1 von nichts abhängt. Damit ist es keine echte Bedingung. In Assembler würde ich eine Endlosschleife auch nicht so schreiben, dass ich in jedem Durchlauf prüfe, ob 1 immer noch ungleich 0 ist und dann einen bedingten Sprung machen. In C(++) muss ich das auch nicht, dank for(;;).

Bei for steht nichts, und man muss, falls man das Idiom nicht kennt, nachdenken.

Ja, wenn man ein Sprachelement nicht kennt, muss man "nachdenken", bzw. es eben lernen.

Bei while steht es explizit da.

Was? Da steht ein "true". Also eine Schleife, die so lange läuft, wie "wahr" wahr ist. Das ist nicht explizit in der Aussage, dass ich eine unbedingte Schleife haben will. Es ist unnötig umständlich. Ich versuche eigentlich immer, möglichst das hinzuschreiben, was ich meine. So schreibe ich z.B. wenn ich einen Integer mit 2 multiplizieren will, * 2 hin und nicht << 1. Und wenn ich eine Schleife ohne Bedingung will, schreibe ich eben eine ohne Bedingung hin und nicht eine mit einer "Bedingung", die auf triviale Weise immer true ist.

Und explizit ist immer besser als implizit.

Richtig.

#7474971
Lesenswert?

Gegen while(1) spricht, dass manche statischen Analyse-Tools meckern, wenn man sie nicht entsprechend konfiguriert. Üblicher ist wahrscheinlich while(1), weil es "lesbarer" ist. Auch wenn for(;;) wohl eher die bestimmungsgemäße Variante für eine Endlosschleife ist.

Aber um sich ein FOREVER-Macro zu machen muss man ja völlig besoffen sein...

#7475117
Lesenswert?

Rolf M. schrieb:

Weil eine 1 von nichts abhängt. Damit ist es keine echte Bedingung.

Natürlich gibt es Bedingungen, die immer wahr sind.

In Assembler würde ich eine Endlosschleife auch nicht so schreiben,

Dann mach das doch auch in C.

Rolf M. schrieb:

Was? Da steht ein "true".

Sehr richtig.

Also eine Schleife, die so lange läuft, wie "wahr" wahr ist. Das ist nicht explizit in der Aussage, dass ich eine unbedingte Schleife haben will.

Sehr explizit. Denn wo ist es denn explizit bei /for(;;)/, dass es eine endlos Schleife sein soll??? Das muss man sich mühsam, aus dem C-Standard raussuchen.

Es ist unnötig umständlich. Ich versuche eigentlich immer, möglichst das hinzuschreiben, was ich meine. So schreibe ich z.B. wenn ich einen Integer mit 2 multiplizieren will, * 2 hin und nicht << 1. Und wenn ich eine Schleife ohne Bedingung will, schreibe ich eben eine ohne Bedingung hin und nicht eine mit einer "Bedingung", die auf triviale Weise immer true ist.

Und dieser Satz stört Dich bei /for(;;)/ nicht?

"An omitted expression-2 is replaced by a nonzero constant"

Der Bedingungsausdruck ist nämlich auch bei /for/ konstant, und damit keine Bedingung nach Deiner Definition.

#7475128
Lesenswert?

Wilhelm M. schrieb:

In Assembler würde ich eine Endlosschleife auch nicht so schreiben,

Dann mach das doch auch in C.

Hä? Das mache ich doch. Das war doch genau der Punkt. Dazu brauche ich aber for, weil das mit while nicht geht.

Rolf M. schrieb:

Was? Da steht ein "true".

Sehr richtig.

Also eine Schleife, die so lange läuft, wie "wahr" wahr ist. Das ist nicht explizit in der Aussage, dass ich eine unbedingte Schleife haben will.

Sehr explizit.

Also ich finde "Schleife: …" eher explizit für eine Endlosschleife als "Schleife, solange wahr wahr ist: …".

Denn wo ist es denn explizit bei /for(;;)/, dass es eine endlos Schleife sein soll???

Es ist sehr explizit darin, dass es eine Schleife ist, die keine Bedingung hat, also eine Endlosschleife, denn es steht ja keine Bedingung dran, von der die weitere Ausführung abhängen könnte.

Das muss man sich mühsam, aus dem C-Standard raussuchen.

Und da sprichst du von an den Haaren herbeigezogenen Dingen. Ich habe schon ganz zu Anfang gelernt, dass bei for() alle drei Teile optional sind. Das sollte eigentlich in jedem Anfängerbuch stehen.

Und dieser Satz stört Dich bei /for(;;)/ nicht?

"An omitted expression-2 is replaced by a nonzero constant"

Nö, warum? Wie der Compiler das umsetzt, ist mir eigentlich egal.

#7475347
Lesenswert?

Rolf M. schrieb:

Es ist sehr explizit darin...

Ersetze explizit mit kryptisch, dann passt es. Oder in deiner Sprache: 's/explizit/kryptisch/'

Rolf M. schrieb:

So schreibe ich z.B. wenn ich einen Integer mit 2 multiplizieren will, * 2 hin und nicht << 1.

Sehr löblich. Warum Du dann bei Schleifen Konstrukte bevorzugst, die aussehen als wenn eine Katze über die Tastatur gelaufen ist, weißt wohl nur du.

#7475551
Lesenswert?

Joe schrieb:

Ein Blick in das C-Standardwerk K&R 'Programmieren in C' zeigt diese Form der Endlosschleife als die von den Autoren bevorzugte. for(;;)

Damit habe ich vor 35 Jahren C gelernt, und selbst da war das Buch schon 10 Jahre alt. Wenn man das als Dogma nehmen möchte, macht man sicher nix falsch. Ich bin trotzdem froh, dass sich die Welt seither etwas weitergedreht hat.

Moderator #7475754
Lesenswert?

Klaus schrieb:

Joe schrieb:

Ein Blick in das C-Standardwerk K&R 'Programmieren in C' zeigt diese Form der Endlosschleife als die von den Autoren bevorzugte. for(;;)

Damit habe ich vor 35 Jahren C gelernt, und selbst da war das Buch schon 10 Jahre alt.

In der 10 Jahre jüngeren 2. Auflage steht das immer noch so :)

Wenn man das als Dogma nehmen möchte, macht man sicher nix falsch. Ich bin trotzdem froh, dass sich die Welt seither etwas weitergedreht hat.

Natürlich hat sich seither vieles verändert, aber wohl kaum die Argumentation für oder gegen for bzw. while zur Bildung von Endlosschleifen.

Chuck Norris würde übrigens while nehmen, aber nicht etwa while(1), sondern

1
while (UINTMAX_MAX) {
2
  ...
3
}

Das ergibt nämlich nicht nur unendlich viele, sondern UINTMAX_MAX mal unendlich viele Schleifendurchläufe, so dass er mehr Spaß beim Abzählen derselben hat. Wenn er damit durch ist, ändert er UINTMAX_MAX in INFINITY ;-)

Gast #7475927
Lesenswert?

Natürlich hat sich seither vieles verändert, aber wohl kaum die Argumentation für oder gegen for bzw. while zur Bildung von Endlosschleifen .

Doch, da hat sich gerade im Embedded einiges getan, sogar bis zur Abschaffung der Schleife als Realisierung eines (Endlosen) Dauerlauf. Und zwar durch Implementierung verschiedener Sleep-Modus und diverse Möglichkeiten des Aufwachens.

Aber das nur für die (Embedded-)Entwickler, die gewillt sind, über den Tellerand einer Akademischen Instrumentalisierung einer Programmiersprache hinaus zu schauen ;-)

BTW: weitaus wichtiger für einen Programmierer als der (absichtliche/unabsichtliche) Start in eine Endlos-Schleife sind die Möglichkeiten eine solche kontrolliert zu verlassen, gerade weil eben das Ende in einer Endlos-Schleife nicht vorgesehen ist ;-)

#7475936
Lesenswert?

Rudolph R. schrieb:

Ansonsten hat aber Jörg da ganz weit oben das schon gut begründet,

Hört sich fast so an, als wärt ihr katholisch: nur weil das vor Äonen schon mal im K&R stand, bedeutet das (für mich) nicht, dass man das so machen sollte. Ich denke da lieber selbst ;-)

hier noch ein Link dazu als Beispiel für Coding Guidelines: https://barrgroup.com/embedded-systems/books/embedded-c-coding-standard/statement-rules/for-while-loops

Dort steht auch gar keine Begründung, sondern nur eine Kodier-Anweisung.

Das Beispiel ist ja völlig irrelevant (s.a. Fußnote dort), weil man eben heute auch C nicht while(1) sondern while(true) schreibt (schreiben sollte).

#7475939
Lesenswert?

Klaus schrieb:

Joe schrieb:

Ein Blick in das C-Standardwerk K&R 'Programmieren in C' zeigt diese Form der Endlosschleife als die von den Autoren bevorzugte. for(;;)

Damit habe ich vor 35 Jahren C gelernt, und selbst da war das Buch schon 10 Jahre alt. Wenn man das als Dogma nehmen möchte, macht man sicher nix falsch. Ich bin trotzdem froh, dass sich die Welt seither etwas weitergedreht hat.

Mir ging es nur um die Frage des TO ob schon mal jemand for(;;) gesehen hat. Ich selber schreibe auch lieber while(1). Letztlich ist es einfach Geschmackssache. Jeder wie er's mag.

(Firma: Eigenbau) #7475945
Lesenswert?

DSGV-Violator schrieb:

Doch, da hat sich gerade im Embedded einiges getan, sogar bis zur Abschaffung der Schleife als Realisierung eines (Endlosen) Dauerlauf. Und zwar durch Implementierung verschiedener Sleep-Modus und diverse Möglichkeiten des Aufwachens.

So, wie ich das bei den Pic-MC verstanden habe, muss zwingend eine Endlosschlaufe vorhanden sein od. bei ASM loop: goto od. branch to loop. Sonst würde der Programmzähler ins Leere laufen oder?

#7475949
Lesenswert?

DSGV-Violator schrieb:

Doch, da hat sich gerade im Embedded einiges getan, sogar bis zur Abschaffung der Schleife als Realisierung eines (Endlosen) Dauerlauf. Und zwar durch Implementierung verschiedener Sleep-Modus und diverse Möglichkeiten des Aufwachens.

Was hat das eine jetzt mit dem anderen zu tun? Ohne Software-Schleife kommt man nur aus wenn das Programm immer wieder durch den Reset-Vector läuft, ansonsten schickt man den Controller am Ende der Schleife in den gewünschten Sleep-Mode und ist durch das Wakeup-Event am Anfang der Schleife. In einen PowerDown Mode zu gehen ist eher sowas wie das Programm zu beenden um irgendwann später mal neu zu starten, aber doch nicht was für den regulären Umlauf, dafür dauert das Aufwachen viel zu lange.

#7475955
Lesenswert?

MaWin O. schrieb:

Wilhelm M. schrieb:

Grundsätzlich sind in C/C++ Endlos-Schleifen, die keine Seiteneffekte enthalten, UB

Sie können entfernt werden, ja. Aber, dass sie UB sind, würde ich mal stark bezweifeln. Wo steht das?

1
In a valid C++ program, every thread eventually does one of the following:
2

3
terminate;
4
makes a call to an I/O library function;
5
performs an access through a volatile glvalue;
6
performs an atomic operation or a synchronization operation.
7
This allows the compilers to remove all loops that have no observable behavior, without having to prove that they would eventually terminate because it can assume that no thread of execution can execute forever without performing any of these observable behaviors.

Das bedeutet, dass eine Endlos-Schleife ohne Seiteneffekt kein valides C++ Programm ist. Und das bedeutet, dass es UB ist.

#7475961
Lesenswert?

Wilhelm M. schrieb:

hier noch ein Link dazu als Beispiel für Coding Guidelines:

https://barrgroup.com/embedded-systems/books/embedded-c-coding-standard/statement-rules/for-while-loops

Dort steht auch gar keine Begründung, sondern nur eine Kodier-Anweisung.

Das Beispiel ist ja völlig irrelevant (s.a. Fußnote dort), weil man eben heute auch C nicht while(1) sondern while(true) schreibt (schreiben sollte).

Die Fußnote hast Du also gefunden, da steht auch eine Begründung. Mit while(true) bin ich nicht einverstanden, aber der Grund für meinen Post war auch nicht das for(;;) zu verteidigen oder was anderes abzulehnen, sondern eine konkrete Coding Guideline zu zitieren in welcher das genau so gefordert ist.

"8.4.c. Infinite loops shall be implemented via controlling expression for (;;)."

Wenn man sich an eine Coding Guideline halten muss, dann gibt es da gar keine Diskussion mehr, die Fußnote macht es nur leichter von der persönlichen Vorliebe abzuweichen um am Ende Regel-konformen Code abzuliefern. Hast Du schon mal einen Pull-Request in einem größeren Projekt gemacht?

#7475979
Lesenswert?

Rolf M. schrieb:

Rudolph R. schrieb:

Doch nicht etwa der Scheduler der in einer Endlos-Schleife läuft?

Erstens ist durch den Standard nicht vorgegeben, wie der Scheduler implementiert sein muss, zweitens wüsste ich nicht, wie er ohne "side effects" in der Lage sein soll, Threads zu starten.

Das ist auch nicht relevant dafür das jedes Embedded Programm irgendwo eine Endlos-Schleife haben muss und der Versuch den Goalpost auf Threads zu verschieben eher albern war in dem Zusammenhang.

#7475998
Lesenswert?

Rudolph R. schrieb:

Das ist auch nicht relevant dafür das jedes Embedded Programm irgendwo eine Endlos-Schleife haben muss

Lies dir den Standard-Text halt einfach mal genau durch. Es ist sehr genau definiert (kein UB) wann eine Endlosschleife wegoptimiert werden kann. Eine Embedded-Endlossschleife fällt dort in der Regel nicht darunter. Es sei denn, sie macht nichts nach außen hin sichtbares.

#7476008
Lesenswert?

Rudolph R. schrieb:

Alles nach thread ist doch in dem Kontext hier bedeutungslos.

Nein, denn wenn es keinen Thread gibt, gibt's auch kein Programm, denn auch main() und alles, was von da aufgerufen wird, ist Teil eines Threads. Der Unterschied zu anderen Threads ist lediglich, dass er halt gleich vom System angelegt wird und nicht manuell erzeugt werden muss/kann.

Gast #7476048
Lesenswert?

Was hat das eine jetzt mit dem anderen zu tun?

beides ist eine Implementierung von reaktionsbereiten Dauerlauf.

Ohne Software-Schleife kommt man nur aus wenn das Programm immer wieder durch den Reset-Vector läuft,

Och, zum Verlassen eine Endlosrn Schleifen gibt es noch weitere Möglichkeiten wie break oder goto.

ansonsten schickt man den Controller am Ende der Schleife in den gewünschten Sleep-Mode und ist durch das Wakeup-Event am Anfang der Schleife.

Nö, da ist man am Startvector des jeweiligen WakeUps, der nicht gleich mit dem Start der Schleife sein muß. IRQ ist da beliebt, beim MC68k gabs da die Unterscheidung in Cold und Cool Capture.

In einen PowerDown Mode zu gehen ist eher sowas wie das Programm zu beenden um irgendwann später mal neu zu starten, aber doch nicht was für den regulären Umlauf, dafür dauert das Aufwachen viel zu lange.

Nö, nicht im Embedded insbesonders beim Batteriebetrieb. Da ist Sleep der an häufigsten angenommen Betriebszustand. Sleep- und PowerDown ist nicht unbedingt dasselbe.

Gast #7476194
Lesenswert?

Grad mal im Parser in der Backus.Nauer-Form nachgeschaut.

1
<iteration-statement> ::= while ( <expression> ) <statement>
2
                        | do <statement> while ( <expression> ) ;
3
                        | for ( {<expression>}? ; {<expression>}? ; {<expression>}? ) <statement>

Da stellt sich jetzt die Frage ob einauf seinen Start rückgeppolter Block eine "Iteration" ist und ob es einen Unterschied zwische Iteration (lat. 'itero') und Repitation (lat.: 'repeto') geben muß.

Gast #7476313
Lesenswert?

Rolf M. schrieb:

DSGV-Violator schrieb:

Da stellt sich jetzt die Frage ob einauf seinen Start rückgeppolter Block eine "Iteration" ist und ob es einen Unterschied zwische Iteration (lat. 'itero') und Repitation (lat.: 'repeto') geben muß.

Warum sollte die Frage, welches lateinische Wort das am besten passende wäre, für die Diskussion relevant sein?

Weil eben eine Iteration wie aus dem Mathematischen Prinzip der vollständigen Induktion bekannt keine Wiederholung (im Kreis laufen) ist. Kennzeichnen für eine Iteration (fortschreitend, i.e. Spirale) ist eben der sich ändernde Index, der eben bei der Notation als leere loop fehlt, obwohl essential für eine Iteration.

https://de.wikipedia.org/wiki/Spirale#Ebene_Spiralen https://de.wikipedia.org/wiki/Kreis

#7476992
Lesenswert?

Iteration und Repetition sind verwandt, aber linguistisch nicht gleich: mit Repetition ist die Wiederholung einer Sache in immer derselben Art gemeint. Mit Iteration ist eine Wiederholung gemeint, die sich von den vorherigen unterscheidet. In Bezug auf eine Zustandsmaschine wie ein valides C-Programm (auf einem µC) dürfte es demnach keine wirkliche Repetition gegen. Denn: ein C-Programm ohne Seiteneffekte ist kein valides C-Programm, und damit ändert sich also der Gesamtzustand des Programms (SW und HW). Also haben wir eine Iteration. Viele Linguisten würden allerdings wohl auch den Begriff der Repetition als Oberbegriff bezeichnen, und die Iteration ist dann eben eine spezielle Ausprägung dessen.

#7477027
Lesenswert?

Hallo, Yalu X. schrieb im Beitrag #7477003:

Oder man benutzt statt der Fremdwörter "Iteration" und "Repetition" einfach das deutsche Wort "Schleife" und geht damit automatisch allen Spitzfindigkeiten aus dem Weg :)

Zu einfach, das würde ja jeder verstehen.

rhf

#7477044
Lesenswert?

Hallo,

2 Zitate:

Bjarne Stroustrup "Die etwas eigenartige anmutende Notation for(;;) codiert eine Endloschleife. Eine alternative Anweisung hierfür ist while(true)."

Ulrich Breymann Äquivalenz von for und while. "Eine for Schleife entspricht direkt einer while-Schleife, sie ist im Grunde nur eine Umformulierung, solange nicht continue vorkommt."

Das heißt, ob nun for(;;) oder while(1) ist vollkommen egal. Die Wirkung was es tut ist exakt gleich. Von daher schreibt was euch gefällt. Sonst wird das ein Endlos-Thread. ;-)

#7477049
Lesenswert?

Veit D. schrieb:

Das heißt, ob nun for(;;) oder while(1) ist vollkommen egal.

Das wussten wir (ok, vllt außer dem TO) doch schon alle vorher.

Die Wirkung was es tut ist exakt gleich.

Auch das ist nichts Neues, und darum ging es ja mal wieder überhaupt nicht: es ging doch darum, was "besser lesbar" sei. Und das ist nunmal subjektiv.

Von daher schreibt was euch gefällt.

Natürlich, was denn sonst?

#7477071
Lesenswert?

Eine interessante Frage kam mir an diesem sonntaglichen herumlungern:

Gibt es eine Möglichkeit das Abbrechen einer Endlosschleife (Egal ob als do/while/for...) mittels "break" zu verhindern?

Ich hatte mal den Fall dass ein überzeugter C-Preprozessor Jünger ein "break" gut in den Innereien versteckt hatte... (Dauerte einige Zeit den Fehler zu identifizieren. Danach wurde der Hacker mit reichlich Katzenscheiße beworfen...)

Wilhelm hatte oben doch ein C++ Vorschlag mit

1
repeat<forever>([]{
2
   // ...
3
});

Gibt es da ein Konstrukt?

Gast #7477087
Lesenswert?

Yalu X. schrieb:

Oder man benutzt statt der Fremdwörter "Iteration" und "Repetition" einfach das deutsche Wort "Schleife" und geht damit automatisch allen Spitzfindigkeiten aus dem Weg :)

Wer die Spitzfindigkeit nicht ehrt, ist die C-Syntax nicht wert ;-)

Siehe auch: https://en.wikipedia.org/wiki/International_Obfuscated_C_Code_Contest#Flight_simulator

Abgesehen davon das mit einem nur grob ausgebildeten Gefühl für die Schriftsprache aus dem schmückenden "Schleife knüpfen/binden" schnell ein strangulierendes "Schlinge knüpfen/binden" wird.

Schlinge, Schleife ... alles nur Gestricke ;-)

#7477121
Lesenswert?

Wilhelm M. schrieb:

Damit sollte doch die Realisierung klar sein, oder?

OK, du meinst vermutlich ein Konstrukt ala

1
template <typename T> void forever(T lambda) {
2
    while (true) {
3
        lambda();
4
    }
5
}
6

7
int main() {
8
    forever([]() {
9
        //...
10
    }); 
11
    return 0;
12
}

Aber eine Endlosschleife muss trotzdem erstellt werden. Ohne sehe ich keine Lösung.

#7477123
Lesenswert?

Klaus H. schrieb:

Tatsächlich stehe ich auf dem Schlauch. Es muss ja zur Compilezeit aufgelöst werden können. Das geht IMHO nur wenn ich im Template eine Endlosschleife ala while(1) {...} nutze, oder?

Genau. Da aber das "break" im Closure stehen würde, wäre es syntaktisch falsch.

Dann hab ich aber ja ursprüngliche Konstrukt.

Naja, in dem Funktionstemplate kannst Du dann alles benutzen, was wir hier diskutiert haben, auch Dein goto ;-)

#7477126
Lesenswert?

Klaus H. schrieb:

Wilhelm M. schrieb:

Damit sollte doch die Realisierung klar sein, oder?

OK, du meinst vermutlich ein Konstrukt ala

1
> template <typename T> void forever(T lambda) {
2
>     while (true) {
3
>         lambda();
4
>     }
5
> }
6
> 
7
> int main() {
8
>     forever([]() {
9
>         //...
10
>     });
11
>     return 0;
12
> }
13
>

Ich hatte verschiedene Spezialisierungen in meinem Beispiel benutzt, damit kann man es noch etwas ausgestalten.

Oder einfach:

1
void forever(auto f) {
2
    while (true) {
3
        f();
4
    }
5
}

Was Du übergeben bekommst, ist keine Lamba-Expression, sondern das Ergebnis(!) einer solchen, also ein Closure. Daher ist der Parametername "lambda" nicht gut. Es ist einfach ein Funktionsobjekt "f", das kann auch ein Funktor odgl. sein.

Moderator #7477201
Lesenswert?

Wilhelm M. schrieb:

Rolf M. schrieb:

Wilhelm M. schrieb:

Wer generische Lambda-Expressions verstanden hat, der hat C++ verstanden ;-)

Damit hast du keine Probleme, aber dass bei for die Bedingung optional ist, findest du zu kompliziert?

Hallo??? Es ging doch um den TO!

Und nachdem der TO schon mit for(;;) Probleme hatte, glaubst du, dass er dieses hier

Wilhelm M. schrieb:

repeat<forever>([]{ // ... });

auf Anhieb versteht und sogar in der Lage ist, die dafür benötigte Template-Funktion selber zu schreiben? :-)

#7477206
Lesenswert?

Yalu X. schrieb:

Wilhelm M. schrieb:

Rolf M. schrieb:

Wilhelm M. schrieb:

Wer generische Lambda-Expressions verstanden hat, der hat C++ verstanden ;-)

Damit hast du keine Probleme, aber dass bei for die Bedingung optional ist, findest du zu kompliziert?

Hallo??? Es ging doch um den TO!

Und nachdem der TO schon mit for(;;) Probleme hatte, glaubst du, dass er dieses hier

Du bist des Lesens scheinbar auch nicht mächtig. Nachdem schon eine ganze Reihe dämlicher #defines, etc. kam, habe ich diese "Antwort" in den Ring geworfen. Sie reiht sich also ganz dort ein. Allerdings hat sie schon Vorteile, wie manche hier bemerkt haben.

#7477900
Lesenswert?

Klaus schrieb:

Probier es aus und teile uns deine Erkenntnisse mit.

Ich habe den Code eingegeben und auf Kompilieren geklickt. Doch dann tat sich plötzlich hinter meinem Sofa ein riesiges Loch auf. Es schlagen Flammen heraus und in der Ferne, ganz tief drin, höre ich Schreie.

Das stand so nicht im K&R-Buch!

Ich warte mal ab. Vielleicht löst sich das ja von ganz alleine.

Moderator #7477966
Lesenswert?

Da ich gestern in einem anderen Zusammenhang etwas Softwarearchäologie betrieben habe, erinnerte ich mich auch daran, wie ich nach der Lektüre des K&R (1. Auflage) meine ersten Gehversuche in C unternahm und schon damals vor der Frage stand, ob ich für Endlosschleifen besser

1
for (;;)

oder

1
while (1)

schreiben sollte.

Neben der Tatsache, dass im K&R for(;;) explizit als mögliche Schreibweise für Endlosschleifen aufgeführt war, machte ich mir auch Gedanken darüber, was wohl der Compiler aus den beiden Varianten macht.

Irgendeiner der mir zur Verfügung stehenden Compiler (ich weiß nicht mehr genau, welcher), nahm das while(1) tatsächlich wörtlich und erzeugte Code, der zuerst eine 1 in ein Register lud, dieses Register auf 0 prüfte und abhängig vom Ergebnis aus der Schleife heraussprang.

Bei for(;;) hingegen generierte er einfach den Schleifenrumpf gefolgt von einem Sprung zum Schleifenanfang.

Bei den heutigen, optimierenden Compilern, muss man sich solche Gedanken natürlich nicht mehr machen. Da wird sofort (beim GCC sogar mit -O0) erkannt, dass die Bedingung 1 trivialerweise immer erfüllt ist und sie deswegen komplett wegoptimiert werden kann.

Trotzdem frage ich mich, warum man für eine Schleife, deren Rumpf bedingungsLOS immer und immer wieder ausgeführt werden soll, eine Bedingung hinschreiben sollte, nur damit sie der Compiler bei der Codegenerierung wieder entfernt.

Ich schreibe ja auch nicht

1
y = 3 + 10 * x * 1 + 0;

obwohl ich fest davon ausgehen kann, dass das "* 1" und das "+ 0" vom Compiler wegoptimiert wird.

Also lasse ich bei Endlosschleifen auch in Zukunft die Bedingung weg und verwende deswegen weiterhin

1
for(;;)

:)

Persönliche Seite #7478030
Lesenswert?

Yalu X. schrieb:

Irgendeiner der mir zur Verfügung stehenden Compiler (ich weiß nicht mehr genau, welcher), nahm das while(1) tatsächlich wörtlich und erzeugte Code, der zuerst eine 1 in ein Register lud, dieses Register auf 0 prüfte und abhängig vom Ergebnis aus der Schleife heraussprang.

Das war dann im letzten Jahrtausend.

Trotzdem frage ich mich, warum man für eine Schleife, deren Rumpf bedingungsLOS immer und immer wieder ausgeführt werden soll, eine Bedingung hinschreiben sollte, nur damit sie der Compiler bei der Codegenerierung wieder entfernt.

Bedingungslos ist es ja nicht... Die Bedingung ist eben immer wahr.

Bei for(;;) ist verwirrend, das eine leere Bedingung akzeptiert wird, und diese immer wahr ist. Auch nicht intuitiv.

#7478044
Lesenswert?

Hallo,

das wollte ich auch soeben als Gegenkommentar schreiben. :-)

for benötigt auch eine Bedingung und für Endlos eben eine leere Bedingung. Nur was ist eine leere Bedingung? Was will der Programmierer mit "nichts" ausdrücken? Fragen über Fragen und deshalb wird es im Forum auch ständig zu der Nachfrage kommen was for(;;) sein soll, wenn das jemand liest. Mit while(1) ist klar erkennbar das der Programmierer die Bedingung mit "immer wahr" eindeutig konstant festgelegt hat. Das ist meine Logik.

Ich schreibe ja auch nicht y = 3 + 10 * x * 1 + 0;

Und selbst das kann sinnvoll sein, wenn man eine Formel mit Wiedererkennungswert niederschreiben möchte. Pauschal ablehnen würde ich sowas nicht.

Gast #7478062
Lesenswert?

Bedingungslos ist es ja nicht...

Doch, das ist bedingungslos aka ein unconditional jump, also ein "goto".

"goto" hat hier gegenüber der entkernten Schleife den Vorteil das wegen der Sprung-Marke der Umfang der Schleife klar erkennbar ist. Bei einer (verschachtelten) Schleife dagegen muss man genau öffnende { und schliessende Block-token} zählen. Das ist fehlerträchtig.

Besteht man aber darauf das es es doch eine Bedingung wäre die aber zwanghaft true ist fabriziert man längeren Pseudocode, bspw.

CLEAR Reg JMPZ Reg,L_START;

statt: JMP L_START

#7478084
Lesenswert?

Harald K. schrieb:

while (1) { label: if (1) continue; else continue; goto label; }

Den Fall, dass das goto nicht immer richtig funktioniert (Strahlen und so!) würde ich auf jeden Fall noch mit abfangen:

1
nochmal:
2
while (1)
3
{
4
label:
5
  if (1) 
6
    continue; 
7
  else 
8
    continue;
9
  goto label;
10
  goto label;
11
  goto label;
12
  goto label;
13
  goto label;
14
  goto label;
15
}
16
goto nochmal;
17
goto nochmal;
18
goto nochmal;
19
goto nochmal;
20
goto nochmal;
21
goto nochmal;
22
main();
#7478110
Lesenswert?

Johann L. schrieb:

Yalu X. schrieb:

Irgendeiner der mir zur Verfügung stehenden Compiler (ich weiß nicht mehr genau, welcher), nahm das while(1) tatsächlich wörtlich und erzeugte Code, der zuerst eine 1 in ein Register lud, dieses Register auf 0 prüfte und abhängig vom Ergebnis aus der Schleife heraussprang.

Das war dann im letzten Jahrtausend.

Damals hatte ich auch mal einen Compiler, dessen Name ich nicht mehr weiß: was ich aber noch ganz genau weiß,dass es für/while(true)/ den optimalen Code erzeugt hat.

Trotzdem frage ich mich, warum man für eine Schleife, deren Rumpf bedingungsLOS immer und immer wieder ausgeführt werden soll, eine Bedingung hinschreiben sollte, nur damit sie der Compiler bei der Codegenerierung wieder entfernt.

Bedingungslos ist es ja nicht... Die Bedingung ist eben immer wahr.

Das hatte ich oben schonmal geschrieben.

Bei for(;;) ist verwirrend, das eine leere Bedingung akzeptiert wird, und diese immer wahr ist. Auch nicht intuitiv.

Auch das hätte ich oben angemerkt: es steht irgendwo versteckt im C-Standard drin, und mitnichten intuitiv. Man könnte genauso gut argumentieren, dass diese nicht vorhandene Bedingung zu /false/ evaluiert, um unbeabsichtigte Endlos-Iterationen zu verhindern.

Moderator #7478188
Lesenswert?

Johann L. schrieb:

Yalu X. schrieb:

Irgendeiner der mir zur Verfügung stehenden Compiler (ich weiß nicht mehr genau, welcher), nahm das while(1) tatsächlich wörtlich und erzeugte Code, der zuerst eine 1 in ein Register lud, dieses Register auf 0 prüfte und abhängig vom Ergebnis aus der Schleife heraussprang.

Das war dann im letzten Jahrtausend.

Richtig:

Yalu X. schrieb:

nach der Lektüre des K&R (1. Auflage)

Das Buch habe ich zuvor neu im Buchhandel erworben :)

Johann L. schrieb:

Trotzdem frage ich mich, warum man für eine Schleife, deren Rumpf bedingungsLOS immer und immer wieder ausgeführt werden soll, eine Bedingung hinschreiben sollte, nur damit sie der Compiler bei der Codegenerierung wieder entfernt.

Bedingungslos ist es ja nicht... Die Bedingung ist eben immer wahr.

Zumindest in meinen Augen ist es bedingungslos, da die Ausführung des Schleifenrumpfs immer erfolgt soll, also an keinerlei Bedingungen geknüpft ist. Das true oder die 1 als Bedingungen kommt erst ins Spiel, wenn man die Ausführung einer Anweisung eigentlich /nicht/ an eine Bedingung knüpfen möchte, aus rein formalen Gründen aber eine solche verlangt wird. Genau dies ist bei while() der Fall, weil es die Grammatik von C so vorschreibt, nicht aber bei for(), wo die Bedingung optional ist.

Man könnte sich ein "cC" (conditional C) vorstellen, wo grundsätzlich jede Anweisung an eine Bedingung geknüpft ist. Das würde dann bspw. so aussehen:

1
x < lower_limit  :>  x = lower_limit;
2
x > upper_limit  :>  x = upper_limit;
3
true             :>  printf("lower_limit = %d\n", lower_limit);
4
true             :>  printf("x           = %d\n", x);
5
true             :>  printf("upper_limit = %d\n", upper_limit);

In den ersten beiden Anweisungen ist die Bedingung erwünscht, die drei nachfolgenden sollen aber bedingungslos ausgeführt werden. Die Grammatik der Sprache verlangt aber nach einer Bedingung, also schreibt man eben jeweils ein "true" hin, um den Compiler zufriedenzustellen. Wäre es nicht schön, wenn die Bedingung optional wäre, so dass man den Code wie folgt schreiben könnte:

1
x < lower_limit  :>  x = lower_limit;
2
x > upper_limit  :>  x = upper_limit;
3
                     printf("lower_limit = %d\n", lower_limit);
4
                     printf("x           = %d\n", x);
5
                     printf("upper_limit = %d\n", upper_limit);

Oder meinst du, die drei leeren Bedingungen könnten von jemandem als "false" interpretiert werden, was bedeuten würde, dass die printfs nie ausgeführt würden?

cC ist zwar eine hypothetische Sprache, aber in ARM-Assembler kann fast jede Instruktion bedingt ausgeführt werden (was natürlich auch von der CPU-Hardware unterstützt wird), wobei die Bedingung durch einen Zweizeichensuffix festgelegt wird, bspw.

1
  MOVEQ ...  ; Ausführung nur, wenn Z-Flag gesetzt ist
2
  MOVHI ...  ; Ausführung nur, wenn C-Flag gesetzt und Z-Flag gelöscht ist
3
  MOVAL ...  ; Ausführung immer (ALways)
4
  MOV   ...  ; Ausführung immer

Der "AL"-Suffix entspricht also dem "true". Der Bedingungssuffix ist optional. Wenn man ihn weglässt, wird die Instruktion immer ausgeführt. Ich habe noch von niemandem gehört, der bei der bedingungslosen Ausführung von Instruktionen auf dem "AL" bestehen würde mit der Begründung, dass das Weglassen ja auch bedeuten könnte, dass die Ausführung unterbunden wird.

Ja, ich weiß, die ganze Diskussion um das while(1) vs for(;;) ist relativ müßig, und ich spucke ja auch niemanden an, der while(1) verwendet ;-)

#7478205
Lesenswert?

Norbert schrieb:

Weise Männer haben dereinst die sogenannten ›defaults‹ erfunden. Scheint sich bewährt zu haben.

Was sind ›defaults‹?

Für mich ist die Sache glasklar: Durch das Auslassen der Bedingung kommuniziert der Programmierer eindeutig, dass es ihm egal ist, unter welcher Bedingung der Code ausgeführt wird (oder eben nicht ausgeführt wird). Eine konforme und zudem noch faire Implementierung dessen wäre die Entscheidung per Zufallsgenerator.

Moderator #7478207
Lesenswert?

MaWin O. schrieb:

Für mich bedeutet das Fehlen der Bedingung, dass per Zufall entschieden wird, ob die Schleife weiterläuft.

Da du diese Aussage nicht an eine Bedingung (auch nicht an die immer wahre) geknüpft hast, bleibt es also undefiniert, ob du sie wirklich so meinst oder nicht ;-)

MaWin O. schrieb:

Eine konforme und zudem noch faire Implementierung dessen wäre die Entscheidung per Zufallsgenerator.

Ok, ich habe gerade eine Münze entscheiden lassen. Ergebnis: Kopf. Also meinst du das Gegenteil von dem, was du geschrieben hast ;-)

#7478220
Lesenswert?

Yalu X. schrieb:

Zumindest in meinen Augen ist es bedingungslos, da die Ausführung des Schleifenrumpfs immer erfolgt soll, also an keinerlei Bedingungen geknüpft ist.

Der TO ist das beste Beispiel dafür, dass das keineswegs klar ist.

Schreibt man es explizit hin, ist es doch sofort jedem klar! Wie gesagt: wie in ganz vielen anderen Fällen ist explizit besser als implizit.

Yalu X. schrieb:

Ja, ich weiß, die ganze Diskussion um das while(1) vs for(;;) ist relativ müßig, und ich spucke ja auch niemanden an, der while(1) verwendet ;-)

Nach dem Sermon, den Du dazu schreibst, bin ich mir da gerade nicht so sicher ...

Moderator #7478228
Lesenswert?

Wilhelm M. schrieb:

Yalu X. schrieb:

Zumindest in meinen Augen ist es bedingungslos, da die Ausführung des Schleifenrumpfs immer erfolgt soll, also an keinerlei Bedingungen geknüpft ist.

Der TO ist das beste Beispiel dafür, dass das keineswegs klar ist.

Einer, der noch kein C-Buch durchgearbeitet hat, wird beim erstmaligen Anblick von

1
while (1) {
2
  ...
3
}

fragen: "Häh, was soll denn diese Schleife mit nur 1 Durchlauf? Warum lässt man das while nicht einfach weg?"

Ich meine mich vage erinnern zu können, dass wir hier im Forum sogar tatsächlich einmal einen ähnlichen Fall hatten.

#7478238
Lesenswert?

Yalu X. schrieb:

Der Code, den der unwissende Anfänger vorgesetzt bekommt, könnte auch schon älter sein.

In welchem Buch, etc. wird denn die /while/-Iteration mit einer Zählschleife assoziiert? Jeder, der ein C-Buch mal in der Hand hatte, weiß, dass dem nicht so ist. Die "Zählschleife" ist die /for/-loop. Die Frage, die hier eigentlich nach dem Lesen des Buches entstehen sollte, was ist denn "1" für ein Boole'scher Ausdruck? Ist damit "true" gemeint?

Gast #7478247
Lesenswert?

(prx) A. K. schrieb:

K&R erste Fassung von 1978. Wer das durchlas, konnte es kaum übersehen. Wer nicht, war selber Schuld.

Interessant, also ein leerer zweite Term genügt für ne endlos-schleife?!

Na dann, schauen wir mal wie schnell Chuck Norris mit unendlich durch ist:

for (int *pt = malloc(0);;pt++) {}

o.ä.

Moderator #7478250
Lesenswert?

Wilhelm M. schrieb:

Yalu X. schrieb:

Der Code, den der unwissende Anfänger vorgesetzt bekommt, könnte auch schon älter sein.

In welchem Buch, etc. wird denn die /while/-Iteration mit einer Zählschleife assoziiert?

Yalu X. schrieb:

Einer, der noch kein C-Buch durchgearbeitet hat, ...

Du hast offensichtlich das Wörtchen "kein" überlesen. Einer, der das Buch gelesen hat, weiß das natürlich. Er weiß dann aber auch, was for(;;) bedeutet.

Moderator #7478280
Lesenswert?

Wilhelm M. schrieb:

Yalu X. schrieb:

Du hast offensichtlich das Wörtchen "kein" überlesen.

Nein. Warum sollte denn der Ausdruck bei while die Anzahl(!) der Durchläufe sein.

Vielleicht, weil es jemand nicht besser weiß? Er sieht ein "while" und hat vielleicht schon einmal irgendwoher gehört, dass das mit einer Schleife zu tun hat. Dann sieht er noch eine Zahl (in diesem Fall die 1), und überlegt, welche Bedeutung eine Zahl im Schleifenkopf haben könnte. Da ist es doch durchaus naheliegend, dass das die Anzahl der Durchläufe sein könnte.

In deutsch: solange(1).

Wer versucht, Programmcode zu verstehen, indem er ihn ins Deutsche übersetzt, hat schon von vornherein verloren. Aus deinem favorisierten while(true) würde solange(wahr). Ohne entsprechendes Vorwissen (bspw. aus einem Buch) ist das so verständlich wie vorgestern(joghurtbecher).

(Firma: Eigenbau) #7478282
Lesenswert?

Wilhelm M. schrieb:

Der TO ist das beste Beispiel dafür, dass das keineswegs klar ist.

Jetzt muss ich doch noch anmerken, dass es mir schon klar war, dass es sich um eine Endlosschleife handeln musste, nur gesehen hatte ich bisher for(;;) noch nie. Die Firmware von Microchip, anfangs von mir erwähnt, habe ich für meine Bedürfnisse abgeändert und sie funktioniert. Sie treibt seit drei Jahren einen BLDC-Motor an. Apropos bedingt, unbedingt: Folgende Bedingung musste ich in eine andere Schleife einbinden, um den Controller auszuschalten:

while(!PORTBbits.RB2) { blabla; }

#7478285
Lesenswert?

Yalu X. schrieb:

Wilhelm M. schrieb:

Yalu X. schrieb:

Du hast offensichtlich das Wörtchen "kein" überlesen.

Nein. Warum sollte denn der Ausdruck bei while die Anzahl(!) der Durchläufe sein.

Vielleicht, weil es jemand nicht besser weiß?

Und derjenige weiß dann, dass for(;;) einen impliziten Bedingungsteil hat, der immer true ist. Das glaubst Du doch selbst nicht.

In deutsch: solange(1).

Wer versucht, Programmcode zu verstehen, indem er ihn ins Deutsche übersetzt, hat schon von vornherein verloren. Aus deinem favorisierten while(true) würde solange(wahr).

Genau. Und das halte ich für ziemlich selbsterklärend.

(Firma: Eigenbau) #7478307
Lesenswert?

Wilhelm M. schrieb:

Jan S. schrieb:

Jetzt muss ich doch noch anmerken, dass es mir schon klar war, dass es sich um eine Endlosschleife handeln musste, nur gesehen hatte ich bisher for(;;) noch nie.

Du hast es also aus dem Kontext geschlossen ...

Ja, die Firmware, die ich abgeändert habe, stammt aus einer noch älteren Firmware als der anfangs gepostete Codeschnipsel. Im älteren Codeschnipsel benutzte der Programmierer while(1){}. Gruss Jan

Moderator #7478314
Lesenswert?

Wilhelm M. schrieb:

Und derjenige weiß dann, dass for(;;) einen impliziten Bedingungsteil hat, der immer true ist. Das glaubst Du doch selbst nicht.

Das einer, der noch kein C-Buch gelesen hat, das for- leichter als das while-Konstrukt versteht, habe ich nirgends behauptet. Wenn er aber erst einmal weiß, was die drei Teile der for-Schleifenkopfs bedeuten, wird er aus dem Fehlen des mittleren Teils schließen, dass der Programmierer keine Bedingung für die Ausführung des Schleifenrumpfs vorgesehen hat, offensichtlich mit der Absicht, dass dieser bedingungslos, d.h. ohne Einschränkungen ausgeführt wird. Fertig. Das ist alles, was er wissen muss.

Er muss, um zu diesem Schluss zu kommen, nicht den Umweg über die implizite, immer true liefernde Bedingung gehen, sondern den Begriff "Bedingung" genauso wie im normalen Sprachgebrauch betrachten: Wenn ich im realen Leben jemandem eine Zusage mache und knüpfe diese an keinerlei Bedingung, dann lasse ich diese einfach weg.

Beispiel:

Zusage mit Bedingung:

"Wenn es schönes Wetter wird, werde ich dich morgen besuchen."

Zusage ohne Bedingung:

"Ich werde dich morgen besuchen."

und nicht etwa

"Wenn die immer erfüllte Bedingung erfüllt ist, werde ich dich morgen besuchen."

oder

"Wenn wahr, werde ich dich morgen besuchen."

Es kann natürlich sein, dass dein Sprachgebrauch ein anderer ist als meiner. Dann werde ich das natürlich akzeptieren.

#7478341
Lesenswert?

Yalu X. schrieb:

aus dem Fehlen des mittleren Teils schließen, dass der Programmierer keine Bedingung für die Ausführung des Schleifenrumpfs vorgesehen hat, offensichtlich mit der Absicht, dass dieser bedingungslos

Eine Schleife wird aber leider nicht mit 'loop' eingeleitet, sondern mit 'for'. for(;;)? for what? Das ergibt überhaupt keinen Sinn und gehört auf den Müllhaufen der Geschichte.

#7478344
Lesenswert?

Hallo,

eigentlich ist es mir ja egal wer was wie schreibt. Es ist nur erschreckend mitzulesen was für abstruse Begründungen hier aufgefahren werden um seine Ansicht irgendwie zu begründen. Wenn K&R damals for (;;) nicht als Endlosschleife irgendwo niedergeschrieben hätten, wüßte bis heute niemand das dieses unklare Konstrukt zur Endlosschleife mutiert. Denn das geht aus der "for" Beschreibung allein nicht hervor. Das for(;;) wird extra beschrieben das es eine Endlosschleife ist. Da kommt sonst niemand drauf. Im Nachgang werden sich dann komische Begründungen ausgedacht um das zurechtfertigen, wie man im Thread sehr schön beobachten kann. Darüber muss ich mich schon sehr stark wundern. Im Gegensatz zu while. Hieraus geht aus der Beschreibung schon hervor solange die Bedingung wahr ist werden die Anweisungen wiederholt ausgeführt.

und nicht etwa "Wenn die immer erfüllte Bedingung erfüllt ist, werde ich dich morgen besuchen."

Tut mir leid, will dir nicht zu Nahe treten, aber ist auch nur eine abstruse Begründung, eine verdrehte Satzbildung, dafür das du while eben nicht leiden kannst und nicht akzeptierst.

Denn es muss lauten wie es im Lehrbuch steht. Wenn die Bedingung erfüllt ist, werde ich dich morgen besuchen. Oder besser. Solange die Bedingung erfüllt ist, werde ich dich morgen besuchen.

Wie gesagt, verwendet was ihr wollt, aber hört auf Euch irgendwelche lächerlichen Begründungen für irgendwas auszudenken. Nur weil K&R damals nichts besseres einfiel und ihr das nun gewohnt seit und verwendet. Der Fortschritt lebt davon eingeschliffene Dinge zu hinterfragen. Die gesamte Haarspalterei im Thread ist lächerlich.

Ahmen.

#7478399
Lesenswert?

Yalu X. schrieb:

... Er muss, um zu diesem Schluss zu kommen, nicht den Umweg über die implizite, immer true liefernde Bedingung gehen, sondern den Begriff "Bedingung" genauso wie im normalen Sprachgebrauch betrachten: Wenn ich im realen Leben jemandem eine Zusage mache und knüpfe diese an keinerlei Bedingung, dann lasse ich diese einfach weg.

Beispiel:

"Wenn wahr, werde ich dich morgen besuchen."

Es kann natürlich sein, dass dein Sprachgebrauch ein anderer ist als meiner. Dann werde ich das natürlich akzeptieren.

Yalu X. schrieb:

Wer versucht, Programmcode zu verstehen, indem er ihn ins Deutsche übersetzt, hat schon von vornherein verloren. Aus deinem favorisierten while(true) würde solange(wahr). Ohne entsprechendes Vorwissen (bspw. aus einem Buch) ist das so verständlich wie vorgestern(joghurtbecher).

#7478400
Lesenswert?

Yalu X. schrieb:

Yalu X. schrieb:

nach der Lektüre des K&R (1. Auflage)

Ich bezweifle, dass dieses Buch heute noch gelesen wird. Und doch, würde ich dem Kandidaten empfehlen, damit aufzuhören. Sonst diskutieren wird demnächst noch über die Funktionsdeklaration im K&R-Stil bzw. darüber, dass es doch viel einfacher sei, eine Deklaration ohne Parameterliste zu schreiben, und das es eben besser sei, nur Funktionen zu deklarieren, die kein /int/ zurück geben.

Je länger Eure Begründungstexte werden, desto abstruster werden sie.

#7478401
Lesenswert?

Jan S. schrieb:

Wilhelm M. schrieb:

Jan S. schrieb:

Jetzt muss ich doch noch anmerken, dass es mir schon klar war, dass es sich um eine Endlosschleife handeln musste, nur gesehen hatte ich bisher for(;;) noch nie.

Du hast es also aus dem Kontext geschlossen ...

Ja, die Firmware, die ich abgeändert habe, stammt aus einer noch älteren Firmware als der anfangs gepostete Codeschnipsel. Im älteren Codeschnipsel benutzte der Programmierer while(1){}. Gruss Jan

Intressant: ursprünglich stand dort also ein /while/, dass irgendjemand zu einem /for(;;)/ verschlimmbessert hat. Und das machte dann Deine Verständnisschwierigkeiten.

Gast #7478404
Lesenswert?

Wenn er aber erst einmal weiß, was die drei Teile der for-Schleifenkopfs bedeuten, wird er aus dem Fehlen des mittleren Teils schließen, dass der Programmierer keine Bedingung für die Ausführung des Schleifenrumpfs vorgesehen hat, offensichtlich mit der Absicht, dass dieser bedingungslos, d.h. ohne Einschränkungen ausgeführt wird. Fertig.

.. ist der Syntax-fehler. OK, hier gerade nicht, aber eben nur weil der Compiler die Zusatzanforderung - nichts angegeben, ist das gleich wie 1 == 1 reingeschrieben - kennt. An allen möglichen Stellen meckert/warnt der Compiler, das hier und da dem Syntax irgendetwas fehlen könnte (i.e. "Read before written" oder if (a = 0)) aber in diesem Semikolonsalat zaubert er irgendeine prähistorische Regel aus dem Hut, die Alltagsdenken komplett widerspricht ("Mach etwas bis in alle Ewigkeit auch wenn Du nicht explizit dazu aufgeforderst wird").

Siehe auch: https://youtu.be/NgUSe5JpdoU?t=10

Für den Alltag dagegen lernt man, das "nichts sagen" auch nichts bedeutet (rechtliches Nullum). https://de.wikipedia.org/wiki/Schweigen_(Recht)

Wer aus dem Fehlen von Angaben auf irgendetwas schliessen will, sollte wegen aufkeimenden verfolgungswahn zum Psychiater gehen.

#7478407
Lesenswert?

Veit D. schrieb:

Wie gesagt, verwendet was ihr wollt, aber hört auf Euch irgendwelche lächerlichen Begründungen für irgendwas auszudenken. Nur weil K&R damals nichts besseres einfiel und ihr das nun gewohnt seit und verwendet.

Sehe ich auch so, hatte ich oben so geschrieben:

Wilhelm M. schrieb:

Hört sich fast so an, als wärt ihr katholisch: nur weil das vor Äonen schon mal im K&R stand, bedeutet das (für mich) nicht, dass man das so machen sollte. Ich denke da lieber selbst ;-)

Ist das die arabische Version von /Amen/ ?

Ahmen.

#7478412
Lesenswert?

DSGV-Violator schrieb:

[offtopic]

Ist das die arabische Version von /Amen/ ?

Ahmen.

Amen ist schon vom Wortursprung her arabisch resp. semitisch.

Danke, aber das es hebräisch ist, war mir schon klar.

Lediglich die Schreibweisen variieren je nach bevorzugten Schriftsatz: Lautschrift [ˈaːmɛn], hebräisch אָמֵן, altgriechisch ἀμήν, arabisch آمين

Wikipedia kann ich selber lesen ;-)

Und in deutsch wird es üblicherweise als "Amen" geschrieben.

Beitrag #7478413 wurde von einem Moderator gelöscht.
#7478416
Lesenswert?

Aufgrund der obigen Diskussion muss ich natürlich noch den C++-Vorschlag von oben

Beitrag "Re: for(;;){} Schleife"

ändern.

1
iterate<endless>([]{
2
    //...
3
});
4

5
[/¢]
6

7
oder
8

9
[c]
10

11
iterate<times<42>>([]{
12
    //...
13
});

oder

1
iterate(n, []{
2
    //...
3
});

Das schreibe ich natürlich nur, um zu erfahren, wie die Formatierung von C++-Code geschieht, der auch Lambda-Expressions enthält.

Moderator #7478445
Lesenswert?

MaWin O. schrieb:

Yalu X. schrieb:

aus dem Fehlen des mittleren Teils schließen, dass der Programmierer keine Bedingung für die Ausführung des Schleifenrumpfs vorgesehen hat, offensichtlich mit der Absicht, dass dieser bedingungslos

Eine Schleife wird aber leider nicht mit 'loop' eingeleitet, sondern mit 'for'.

Da stimme ich dir zu. Mit "loop" wäre das Ganze noch ein Stückchen besser. Und bei while(true) könnte dann wie in Rust eine Warning (oder noch besser ein Error) ausgegeben werden.

Wilhelm würde aber vermutlich auch loop ablehnen mit der Begründung, dass loop nichts anderes als while(true) mit einer böswillig versteckten, impliziten und immer wahren Bedingung ist ;-)

#7478455
Lesenswert?

177 (178 jetzt) Beiträge über for (;;){} - DAS Anfängerstatement in C an sich.

Dieses Forum ist so was von krank. Diskussion über die Endlosschleife in einer Endlosschleife. Man könnte noch einen neuen Fred aufmachen, wo man über die endlose Diskussion über die Diskussion der Endlosschleife diskutiert?

#7478486
Lesenswert?

Jan S. schrieb:

Bauform B. schrieb:

Im "Betriebssystem" darf es sowieso keine Endlosschleife geben, Problem gelöst ;)

Ich betrachte die ganz am Anfang gepostete Schleife als unbedingt notwendig, sie ist das eigentliche "Betriebssystem", sie fragt pausenlos den Zustand des Tasters ab, der restliche Betrieb läuft praktisch nur noch über Interrupts.

Und warum darf der Taster keinen Interrupt liefern?

Gast #7478487
Lesenswert?

Harald K. schrieb:

Erwähnte ich schon die beeindruckende Dichte geistiger Onanie in diesem Thread hier?

Nun, wenn es dir mit der bloßen Erwähnung der Onanie nicht getan ist, dann lies das Buch über Endlos geflochtene Bänder - in den Achtzigern schaffte es dieses sogar Wochenlang auf die Spiegel-Bestsellerliste:

D. Hofstadter: "Gödel, Escher, Bach - ein Endlos Geflochtenes Band "

Auch heute noch ein Klassiker, der auf keinem intellektuellem Kaffeekränzchen fehlen darf.

https://www.booklooker.de/B%C3%BCcher/Douglas-R-HOFSTADTER+G%C3%B6del-Escher-Bach/id/A02wUkNe01ZZu

https://www.heise.de/blog/Klassiker-neu-gelesen-Goedel-Escher-Bach-4702826.html

https://de.wikipedia.org/wiki/G%C3%B6del,_Escher,_Bach

#7478509
Lesenswert?

Yalu X. schrieb:

MaWin O. schrieb:

Yalu X. schrieb:

aus dem Fehlen des mittleren Teils schließen, dass der Programmierer keine Bedingung für die Ausführung des Schleifenrumpfs vorgesehen hat, offensichtlich mit der Absicht, dass dieser bedingungslos

Eine Schleife wird aber leider nicht mit 'loop' eingeleitet, sondern mit 'for'.

Da stimme ich dir zu. Mit "loop" wäre das Ganze noch ein Stückchen besser. Und bei while(true) könnte dann wie in Rust eine Warning (oder noch besser ein Error) ausgegeben werden.

Wilhelm würde aber vermutlich auch loop ablehnen mit der Begründung, dass loop nichts anderes als while(true) mit einer böswillig versteckten, impliziten und immer wahren Bedingung ist ;-)

Wieso sollte ich das ablehnen? Anscheinend hast Du immer noch gar nichts verstanden. Ein

1
loop {
2
   // ...
3
}

wäre doch super.

Ein

1
loop(auto i : n) {
2
   // ...
3
}

wäre doch auch prima.

Nur ein

1
loop(;;) {
2
   // ...
3
}

wieder Mist.

Gast #7478515
Lesenswert?

Ein

1
 loop {
2
    // ...
3
 }

wäre doch super.

Aber nur in einem mickrigen Drei-Zeilen Codeschnipsel. Erstreckt sich der Schleifenköper aber über mehr als nur 40 Zeilen und umschliesst als Schachtel weitere Blöcke und steckt womöglich selbst in ein paar verschachtelten Schachtel-Blöcken reichen '{' und '}' als Orientierung für Anfang und Ende nicht aus. Da sind Label und oder comments handreichender. Aber offensihtlich sind Labels wie goto die ungeliebten Stiefkinder in C.

https://www.geeksforgeeks.org/local-labels-in-c/

#7478518
Lesenswert?

for(;;) musste ich erst nachschlagen und macht für mich auch keinen wirklichen Sinn weil ich nicht davon ausgehen kann, dass das weglassen von Argumenten automatisch zu einer Endlosschleife führt. Ohne Internet wäre ich also aufgeschmissen.

while(1) oder while(true) ist auf Anhieb klar, wenn man halbwegs weiß wie while funktioniert.

Ich schreibe daher auch

1
if(x > 9)
2
  y = 100;
3
else
4
  y = 200;

anstatt

1
y = x > 9 ? 100 : 200;

Ich bin aber auch kein Profi.

#7478520
Lesenswert?

Hallo, Veit D. schrieb im Beitrag #7478344:

Wenn K&R damals for (;;) nicht als Endlosschleife irgendwo niedergeschrieben hätten...

Tja, haben sie eigentlich gar nicht. Ich habe mal in in der deutschen Übersetzung von "Programmieren in C" von 1990 nachgesehen. Da wird in Kapitel 3.5 "Schleifen - /while/ und /for/" die entsprechende Syntax beschrieben und darauf hingewiesen das beide Schleifenkonstrukte zueinander äquivalent sind:

1
for ( expr1 ; expr2 ; expr3 )
2
    statement

ist äquivalent zu

1
expr1 ;
2
while ( expr2 ) {
3
    statement;
4
    expr3;
5
}

Weiterhin heißt es (wurde hier auch schon des Öfteren erwähnt): "Fehlt die Bedingung expr2, so gilt sie immer als wahr". Als Beispiel wird jetzt

1
for (;;) {
2
    ...
3
}

angeführt, Zitat "...ist also eine 'unendliche Schleife', die vermutlich durch Anweisungen wie break oder return beendet wird". Und weiter heißt es :"Ob man while oder for bevorzugt, beruht weitgehend auf persönlicher Vorliebe." Ich habe auch nirgend wo sonst im Buch eine explizite Forderung gefunden das man für Endlosschleifen das for()-Konstrukt zu verwenden hat. Es bleibt also jedem selbst überlassen welches Konstrukt er für seine "Endlosschleifen" benutzt.

...wüßte bis heute niemand das dieses unklare Konstrukt zur Endlosschleife mutiert.

Ich weiß noch genau wie ich zum ersten mal eine while(1) in einem Quelltext gesehen und ich mich gewundert habe wie das funktioniert wo doch der sonst üblich Vergleichsausdruck fehlt. Auch heute noch finde ich diese Form der Endlosschleife merkwürdig, unlogisch und für einen Anfänger schwer zu verstehen.

rhf

P.S. Und im Übrigen bin ich der Meinung, das die Konstruktion von Endlosschleifen mit while() oder for() die eigentliche Funktion verschleiert. Deshalb ist für mich die einzig wahre Konstruktion die mit

1
Label:
2
    ...
3
goto Label

Wenn dann noch Label entsprechend benannt wird, weiß jeder sofort und unmissverständlich was gemeint ist

Gast #7478533
Lesenswert?

(prx) A. K. schrieb:

DSGV-Violator schrieb:

lies das Buch über Endlos geflochtene Bänder - in den Achtzigern schaffte es dieses sogar Wochenlang auf die Spiegel-Bestsellerliste:

Ich fragte mich allerdings schon damals, wieviele derer, die es gekauft hatten, es auch in signifikantem Umfang gelesen hatten.

Nun, das Bemerkenswerte an diesem Buch ist, dass sich, aufgrund der zahlreichen Zeichnungen von, den Buchtitel mit-tragenden, Maurits Cornelis Escher, ein Zugang allein durch Betrachtung der Illustration eine Zugangsmöglichkeit ergibt. Andere mögen sich das Buch über die Ausführungen zur Musikgeschichte (Bach) erschliessen, persönlich führte der Weg über die Ausführungen zur formalen Logik und (Östlicher) Philosophie. Die Darstellungen zum maschinellen Rechnen/Computerei funktionieren da anschauliche beispiele zu einem (sehr) abstrakten) Thema. Aber das Buch ist tatsächlich keine kleine Kost die man so nebenher bei der Fahrt im ÖPNV "wegfuttert". Manche lesen ein Leben lang immer mal wieder darin. Fast so wie die "Bibelforscher" ;-)

#7478596
Lesenswert?

DSGV-Violator schrieb:

Aber nur in einem mickrigen Drei-Zeilen Codeschnipsel. Erstreckt sich der Schleifenköper aber über mehr als nur 40 Zeilen und umschliesst als Schachtel weitere Blöcke und steckt womöglich selbst in ein paar verschachtelten Schachtel-Blöcken reichen '{' und '}' als Orientierung für Anfang und Ende nicht aus.

Schon mal was von Funktionen gehört?

#7478603
Lesenswert?

Roland F. schrieb:

Tja, haben sie eigentlich gar nicht. Ich habe mal in in der deutschen Übersetzung von "Programmieren in C" von 1990 nachgesehen. Da wird in Kapitel 3.5 "Schleifen - while und /for/" die entsprechende Syntax beschrieben und darauf hingewiesen das beide Schleifenkonstrukte zueinander äquivalent sind:

Ach was, schon mal was von Schleifentransformation gehört?

Gast #7478616
Lesenswert?

Das ganz einfach an dieser dummen Praxis while(1) statt besser while(true) hinzuschreiben.

Naja, das Dumme ist, das Standard-C in der Praxis keine boolean Werte wie 'true' kennt.

Ist halt einer der Geburtsfehler dieser Sprache. Oder eben nicht, kommt darauf an, ob man C eher als gezuckerten Assembler für Embedded oder als Hochsprache für Mathematisch-Abstrakte Aufgabenstellungen die sich wenig um numerische Representation schert, versteht/benutzt.

Beitrag "Boolean in C"

Schon mal was von Funktionen gehört?

Klar, würde hier u.a. wegen Context-switch/Stack-Operationen das Problem noch vergrößern statt verkleinern.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren