Forum: Compiler & IDEs for(;;){} Schleife


von MaWin O. (mawin_original)


Lesenswert?

DSGV-Violator schrieb:
>> Mindestens seit C99 aber schon.
>
> Nö.

doch.

https://en.cppreference.com/w/c/types

von DSGV-Violator (Gast)


Lesenswert?

MaWin O. schrieb:

> https://en.cppreference.com/w/c/types

Ich hau mich weg, das steht "removed in C23". Und 
"Bequemlichkeits-Makro",  die reinste Warmduscherei ...

von MaWin O. (mawin_original)


Lesenswert?

DSGV-Violator schrieb:
> Ich hau mich weg

Freut mich, dass du dich auch über kleine Dinge amüsieren kannst.

von Wilhelm M. (wimalopaan)


Lesenswert?

DSGV-Violator schrieb:
> Ich hau mich weg, das steht "removed in C23". Und
> "Bequemlichkeits-Makro",  die reinste Warmduscherei ..

Richtig, dafür ist es ab C23 ein eigener Typ.

von DSGV-Violator (Gast)


Lesenswert?

MaWin O. schrieb:
> DSGV-Violator schrieb:
>> Ich hau mich weg
>
> Freut mich, dass du dich auch über kleine Dinge amüsieren kannst.

Über den Unterschied zwischen "Weg Hauen" und "Amüsement" müsste man 
sich mal in Ruhe unterhalten ...

Ich finde es jedenfalls nicht hilfreich, das hier die Benutzung von 
"abgeschnittenen Sonderlocken" aus Gründen der Bequemlichkeit 
vorgeschlagen wird.

von MaWin O. (mawin_original)


Lesenswert?

DSGV-Violator schrieb:
> Ich finde es jedenfalls nicht hilfreich, das hier die Benutzung von
> "abgeschnittenen Sonderlocken" aus Gründen der Bequemlichkeit
> vorgeschlagen wird.

Kann es sein, dass es an deinem Leseverständnis hapert?

von DSGV-Violator (Gast)


Lesenswert?

Wilhelm M. schrieb:

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

> Mindestens seit C99 aber schon.

> Richtig, dafür ist es ab C23 ein eigener Typ.

Alter Falter, nicht mal Jahreszahlen kriegt man hier richtig gebacken 
...

Ja klar, in irgendeinem Standard von anno 
"AchHatDerHundDieEckeMitDerJahreszahlGefressen" steht es so oder doch 
anders und warum schreibt man überhaupt "Standards" wenn man diese wie 
politische Parteien je nach Wahlkampf umfrisiert ...

Geburtsfehler ist nun mal Geburtsfehler, da kann auch plastische 
Chirurgie nur den Anschein aufhübschen aber nicht den Wesenskern.

von Wilhelm M. (wimalopaan)


Lesenswert?

DSGV-Violator schrieb:
> Alter Falter, nicht mal Jahreszahlen kriegt man hier richtig gebacken
> ...

Hä???

von MaWin O. (mawin_original)


Lesenswert?

DSGV-Violator schrieb:
> Alter Falter, nicht mal Jahreszahlen kriegt man hier richtig gebacken

Ab C99 gibt es bool, true und false, die sich wie echte Booleans 
verhalten. Also nur die Werte 0 und 1 annehmen können. Was brauchst du 
noch?

von Bauform B. (bauformb)


Lesenswert?

MaWin O. schrieb:
> Ab C99 gibt es bool, true und false, die sich wie echte Booleans
> verhalten. Also nur die Werte 0 und 1 annehmen können. Was brauchst du
> noch?

Wie jetzt? Es muss doch heissen "nur die Werte zwischen 0.0 und 1.0". 
Wie will man sonst die-ganze-Wahrheit von der einfachen Aussage 
unterscheiden? Hier ist for(;;) auch wieder überlegen, weil, wie lange 
läuft eine Endlosschleife while(true) mit true = 0.99?

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


Lesenswert?

DSGV-Violator schrieb:
> Es gibt da schon einen Unterschied zwischen Sprache und
> Standardbibliotheken.

Aus Sicht des Sprachstandards nicht wirklich, beides ist "the 
implementation".

Dass man "true" und "false" so spät nicht einfach ohne Headerfile neu 
definieren durfte, ist einfach mal den vielen existierenden Programmen 
geschuldet, die sowas vorher selbst definiert haben durften. Der Typ 
_Bool ist aber dennoch intrinisch, denn dessen Bezeichner liegt im 
implementation namespace. <stdbool.h> mappt ihn dann nur auf bool.

von Norbert (der_norbert)


Lesenswert?

Veit D. schrieb:
> 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.

Das ist natürlich Quadratunsinn!

Im K&R steht es EXPLIZIT drin.

K&R Ed.2 page 56
1
Grammatically, the three components of a for loop are expressions. Most commonly, expr 1 and expr 3 are assignments or function calls and expr 2 is a relational expression. Any of the three parts can be omitted, although the semicolons must remain. If expr 1 or expr 3 is omitted, it is simply dropped from the expansion. If the test, expr 2 , is not present, it is taken as permanently true,

Nicht nur drüber reden … LESEN!

von Hans H. (loetkolben)


Lesenswert?

Ich schreibe die Endlosschleife immer so:
1
do {
2
 // many
3
 // lines
4
 // of
5
 // code
6
} while (1=1);

denn ich finde die Überraschung muß am Ende kommen.

von Wilhelm M. (wimalopaan)


Lesenswert?

Hans H. schrieb:
> Ich schreibe die Endlosschleife immer so:
>
>
1
> do {
2
>  // many
3
>  // lines
4
>  // of
5
>  // code
6
> } while (1=1);
7
>
>
> denn ich finde die Überraschung muß am Ende kommen.

Stark! Toller fehlertoleranter  Compiler.

von Norbert (der_norbert)


Lesenswert?

Hans H. schrieb:
> Ich schreibe die Endlosschleife immer so:
> do {
>  // many
>  // lines
>  // of
>  // code
> } while (1=1);
>
> denn ich finde die Überraschung muß am Ende kommen.

Parabelförmig vomittierend…

von (prx) A. K. (prx)


Lesenswert?

Hans H. schrieb:
> } while (1=1);

Ich finde ja while(0<1) eleganter.

von Veit D. (devil-elec)


Lesenswert?

Wilhelm M. schrieb:

> Ist das die arabische Version von Amen ?
>> Ahmen.

Klarer Syntaxfehler von mir. Davor hätte mich bestimmt der Compiler 
gewarnt. Mir fehlt nur noch eine Begründung wie man das doch noch als 
Richtig erklären könnte. Dann wäre es Thread Konform.  :-)  :-)

von Wilhelm M. (wimalopaan)


Lesenswert?

In C++ sollte man ganz klar nur noch HOFs für Iterationen verwenden:
1
    iterate(3)(f1);
2
3
    iterate(7)([](const auto i){
4
        r = i;
5
    });
6
    iterate(9)([]{
7
        r = 42;
8
    });
9
    iterate(Forever{})([]{
10
        r *= 2;
11
    });

;-)

von Rolf M. (rmagnus)


Lesenswert?

Yalu X. schrieb:
> 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 das meinte ich weiter oben, als ich davon sprach, dass es keine 
richtige Bedingung sei. Technisch ist es natürlich eine Bedingung, aber 
ich schreibe sie nur hin, weil sie eben formal nötig ist und nicht, weil 
ich tatsächlich eine will.

DSGV-Violator schrieb:
> 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

… dann sollte man sich mal schleunigst daran machen, den Code sauberer 
zu strukturieren.

Wilhelm M. schrieb:
> Auch das hätte ich oben angemerkt: es steht irgendwo versteckt im
> C-Standard drin, und mitnichten intuitiv.

Wo das im C-Standard steht, wird für die wenigsten relevant sein, weil 
sie da eh nicht reinschauen. Wichtiger ist, wo es im Lehrbuch steht, und 
die Optionaliät der drei Ausrücke in einer for-Schleife wird da doch 
hoffentlich im Kapitel über Schleifen drin stehen, sonst taugt es nicht 
viel.
Und ich finde es im übrigen sehr wohl intuitiv, mehr noch als wenn ich 
irgendwas als Bedingung hinschreiben muss, nur um der Form genüge zu 
tun.

> Man könnte genauso gut argumentieren, dass diese nicht vorhandene
> Bedingung zu false evaluiert, um unbeabsichtigte Endlos-Iterationen zu
> verhindern.

Das wäre nun wirklich an den Haaren herbeigezogen. Warum hätten sie die 
Bedingung dann überhaupt optional gemacht? Eine extra eingebaute 
zusätzliche Option, nur um explizit Schleifen schreiben zu können, die 
niemals ausgeführt werden? Das ergäbe nun wirklich gar keinen Sinn.

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.

Hier hat jetzt genau einer mal nachgefragt. Es gibt hier zu allerhand 
Bestandteilen verschiedener Sprachen Fragen. Das bedeutet nicht, dass 
das alles völlig unintuitiv 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.

Bis auf das "es" sind wir uns da einig. Für mich ist "es" die 
Bedingungslosigkeit der Schleife, denn das ist es ja, was ich eigentlich 
erreichen will. Und Bedingungslosigkeit drückt man am besten dadurch 
aus, dass man keine Bedingung angibt.

Wilhelm M. schrieb:
> iterate(Forever{})([]{
>         r *= 2;
>     });

Was lisp kann (Klammernorgien), das bekommen wir in C++ doch auch locker 
hin. ;-)

Yalu X. schrieb:
> Harald K. schrieb:
>> Erwähnte ich schon die beeindruckende Dichte geistiger Onanie in diesem
>> Thread hier?
>
> Ja, jetzt schon zum dritten Mal. Das wird doch nicht etwa eine
> Endlosschleife?

Was er vergessen hat zu erwähnen ist, warum er eigentlich immer noch 
mitliest, wenn er die Diskussion so blöd findet.

von Wilhelm M. (wimalopaan)


Lesenswert?

Rolf M. schrieb:
> Bis auf das "es" sind wir uns da einig. Für mich ist "es" die
> Bedingungslosigkeit der Schleife, denn das ist es ja, was ich eigentlich
> erreichen will.

Wenn Du explizit das Fehlen von etwas hinschreiben möchtest, dann 
brauchst Du dafür eben ein Konstrukt, was Du schreiben kannst.

Also etwa:
1
for(;Unconditional{};) {
2
3
}

Könnte man natürlich (in C++) machen. Oder in C eben mit for(;"ever";);

Wenn Du etwas weglässt, ist es eben nicht mehr explizit, sondern 
implizit.

: Bearbeitet durch User
von Yalu X. (yalu) (Moderator)


Lesenswert?

Rolf M. schrieb:
> Wilhelm M. schrieb:
>> iterate(Forever{})([]{
>>         r *= 2;
>>     });
>
> Was lisp kann (Klammernorgien), das bekommen wir in C++ doch auch locker
> hin. ;-)

Während in Lisp hauptsächlich runde Klammern verwendet werden, kann man
in C++ alle Klammersymbole, die ASCII hergibt, also ()[]{}<>, fast nach
Belieben mischen.

Ich würde übrigens im obigen Lambda-Ausdruck die leere und deswegen
optionale Parameterliste explizit hinschreiben, weil sonst – ähnlich wie
bei der weggelassenen Bedingung in for(;;) – überhaupt nicht klar ist,
was der Compiler dafür einsetzt. Also so:
1
iterate(Forever{})([](){
2
//             \___ ___/
3
//                 V
4
//               9, wow

Wilhelm schafft es sicher auch noch, das Beispiel mit ein paar
Template-Klammern (<>) aufzuhübschen, dann sind wir nicht mehr weit weg
von der Programmiersprache ], die zu einem würdigen Nachfolger von C++
werden könnte:

  https://esolangs.org/wiki/Right_bracket

von Rolf M. (rmagnus)


Lesenswert?

Wilhelm M. schrieb:
> Wenn Du explizit das Fehlen von etwas hinschreiben möchtest,

Es fehlt doch aber nichts.

> dann brauchst Du dafür eben ein Konstrukt, was Du schreiben kannst.

Warum sollte ich was hinschreiben müssen, um damit auszudrücken, dass es 
eigentlich nichts zum hinschreiben gibt?

von Rudolph R. (rudolph)


Lesenswert?

Tschuldigung, bin spät dran den Thread weiter laufen zu lassen. :-)

https://pclintplus.com/gmp/demo/
1
int main(void)
2
{
3
    while (1)
4
    {
5
    }
6
7
    for (;;)
8
    {
9
    }
10
}

C11/No Standard Library
Autosar19:
note 9177: condition of 'while' statement has non-Boolean type 'int' 
[AUTOSAR Rule A5-0-2]
info 716: infinite loop via while

MISRA C 2012:
note 9036: essential type of condition of 'while' statement is 'signed8' 
but should be boolean [MISRA 2012 Rule 14.4, required]
info 716: infinite loop via while

Die Info 716 wird immer getriggert, also nach MISRA und Autosar ist 
while(1) praktisch doppelt böse. :-)

BARR-C 2018 hatte ich ja schon erwähnt.

Im SEI CERT C Coding Standard habe ich spontan nichts gefunden, also im 
Netz, die Präferenz scheint da aber bei while(true) zu liegen.
1
#include <stdbool.h>
2
3
int main(void)
4
{
5
    while (true)
6
    {
7
    }
8
}

MISRA C 2012:
info 716: infinite loop via while
supplemental 893: expanded from macro 'true' (line 17)


Interessant fände ich jetzt noch andere Beispiel von Coding Guidelines.

Ich habe gerade die ISO/IEC 17961 gefunden, bzw. natürlich nur den 
Hinweis und nicht den Standard selber.
https://www.iso.org/standard/61134.html

von Bauform B. (bauformb)


Lesenswert?

Rudolph R. schrieb:
> Interessant fände ich jetzt noch andere Beispiel von Coding Guidelines.

Ich bin erschüttert. Richtige Betriebssysteme brauchen Endlosschleifen, 
aber die NASA nicht.
1
C Style and Coding Standards for SunOS
2
Bill Shannon
3
Copyright  1993 by Sun Microsystems, Inc.
4
5
for statements
6
  for (initialization; condition; update) { statements; }
7
  When using the comma operator in the initialization or update clauses
8
  of a for statement, it is suggested that no more than three variables
9
  should be updated. More than this tends to make the expression too
10
  complex. In this case it is generally better to use separate
11
  statements outside the for loop (for the initialization clause),
12
  or at the end of the loop (for the update clause).
13
14
  The infinite loop is written using a for loop.
15
  for (;;) { statements; }
1
/*
2
 * The NetBSD source code style guide.
3
 * (Previously known as KNF - Kernel Normal Form).
4
 *
5
 *      from: @(#)style 1.12 (Berkeley) 3/18/94
6
 */
7
 /* Forever loops are done with for's, not while's. */
1
C STYLE GUIDE, AUGUST 1994
2
SOFTWARE ENGINEERING LABORATORY SERIES SEL-94-003
3
National Aeronautics and Space Administration
4
Goddard Space Flight Center
5
Greenbelt, Maryland 20771
Dieses 100-Seiten Werk erwähnt solche Schleifen mit keiner Silbe.
Edit: linux-source-4.19/Documentation/process/coding-style.rst schreibt 
auch nichts vor.

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Yalu X. schrieb:
> Während in Lisp hauptsächlich runde Klammern verwendet werden, kann man
> in C++ alle Klammersymbole, die ASCII hergibt, also ()[]{}<>, fast nach
> Belieben mischen.

Das geht in C auch ;-) Allerdings ist in C die Wahrscheinlichkeit, dass 
sich dadurch ein valides C Programm ergibt, geringer.

> Ich würde übrigens im obigen Lambda-Ausdruck die leere und deswegen
> optionale Parameterliste explizit hinschreiben, weil sonst – ähnlich wie
> bei der weggelassenen Bedingung in for(;;) – überhaupt nicht klar ist,
> was der Compiler dafür einsetzt.

Leider falsch.
Wenn Du in for(;true;) oder for(;false;) den Boole'schen Wert weglässt, 
wird dafür (in C) ein implementation-defined Wert != 0 eingesetzt.

Wenn Du in dem Lambda-Ausdruck [](){} die leere Parameterliste weglässt, 
wird die durch nichts, auch nichts anderes ersetzt.

Also so:
> iterate(Forever{})([](){
> //             \___ ___/
> //                 V
> //               9, wow
>
> Wilhelm schafft es sicher auch noch, das Beispiel mit ein paar
> Template-Klammern (<>) aufzuhübschen,

Hatte ich doch schon, oder?

von DSGV-Violator (Gast)


Lesenswert?

Bauform B. schrieb:
> Rudolph R. schrieb:
>> Interessant fände ich jetzt noch andere Beispiel von Coding Guidelines.
>
> Ich bin erschüttert. Richtige Betriebssysteme brauchen Endlosschleifen,
> aber die NASA nicht.

Naja es gibt halt neben "richtigen" Betriebssystemen auch 
Betriebssysteme die im Space steuerbar sein müßen. Da sind 
Endlosschleifen das letzte was man will, siehe bspw. WatchDogtimer.

von Norbert (der_norbert)


Lesenswert?

DSGV-Violator schrieb:
> Naja es gibt halt neben "richtigen" Betriebssystemen auch
> Betriebssysteme die im Space steuerbar sein müßen. Da sind
> Endlosschleifen das letzte was man will, siehe bspw. WatchDogtimer.

Nun, wenn es ein Task ist, welcher die lebenserhaltenden Systeme steuert 
und überwacht … also ich hätte da schon gerne eine Endlos-Schleife. ;-)

von Rolf M. (rmagnus)


Lesenswert?

Norbert schrieb:
> Nun, wenn es ein Task ist, welcher die lebenserhaltenden Systeme steuert
> und überwacht … also ich hätte da schon gerne eine Endlos-Schleife. ;-)

Ich denke auch, dass es eher unschön ist, wenn beim Wiedereintritt die 
Raketensteuerung aussetzt, weil sich das Programm beendet hat.

Wilhelm M. schrieb:
> Wenn Du in dem Lambda-Ausdruck [](){} die leere Parameterliste weglässt,
> wird die durch nichts, auch nichts anderes ersetzt.

Na sicher wird sie das - durch eine leere Parameterliste. Das steht so 
im C++-Standard: "If a lambda-expression does not include a 
lambda-declarator, it is as if the lambda-declarator were ()."
Also darfst du sie deiner eigenen Logik folgend nie weglassen.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Wilhelm M. schrieb:
> Yalu X. schrieb:
>> Ich würde übrigens im obigen Lambda-Ausdruck die leere und deswegen
>> optionale Parameterliste explizit hinschreiben, weil sonst – ähnlich wie
>> bei der weggelassenen Bedingung in for(;;) – überhaupt nicht klar ist,
>> was der Compiler dafür einsetzt.
>
> Leider falsch.
> Wenn Du in for(;true;) oder for(;false;) den Boole'schen Wert weglässt,
> wird dafür (in C) ein implementation-defined Wert != 0 eingesetzt.
>
> Wenn Du in dem Lambda-Ausdruck [](){} die leere Parameterliste weglässt,
> wird die durch nichts, auch nichts anderes ersetzt.

Nix falsch (Rolf hat dich auf deinen Trugschluss bereits hingewiesen).
Weil dir keine echten Argumente mehr einfallen, begibst dich gerade auf
das Niveau der reinen Wortklauberei. Lass es mich dir noch etwas
ausführlicher erklären, als es Rolf bereits getan hat:

Natürlich hast du insofern recht, dass bei der Spezifikation des
for-Statements im C-Standard das Wort "replaced" auftaucht:

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

In der Spezifikation der Lambda-Expression im C++-Standard wird der
entsprechende Sachverhalt mit "as if" formuliert:

"If a lambda-expression does not include a lambda-declarator, it is as
if the lambda-declarator were ()."

Da auch beim for-Statement die as-if-Regel gilt, kann der obige Satz
ohne die geringste Änderung seiner Aussage wie folgt umformuliert
werden:

"If a for statement does not include expression-2, it is as if
expression-2 is a nonzero constant."

Uns siehe da, das "replaced", an dem du dich so festkrallst, ist weg,
und die fehlenden expression-2 wird einfach durch nichts ersetzt.

Genauso gut kann der Satz mit dem lambda-declarator ohne die geringste
Änderung seiner Aussage wie folgt formuliert werden:

"An omitted lambda-declarator is replaced by ()."

Jetzt steht auch hier ein "replaced". Die fehlende Parameterliste wird
also durch die leere Parameterliste (ein einfaches Klammerpaar) ersetzt.

Wer also darauf besteht, im Kopf einer Endlosschleife die Bedingung
"true" hinzuschreiben, der sollte konsequenterweise bei parameterlosen
Lambda-Ausdrücken die leere Parameterliste hinschreiben. Wenn du das
partout ablehnst, hat es wenig Sinn, mit dir weiter über Logik in der
Programmierung zu diskutieren.

: Bearbeitet durch Moderator
von DSGV-Violator (Gast)


Lesenswert?

> Ich denke auch, dass es eher unschön ist, wenn beim Wiedereintritt die
> Raketensteuerung aussetzt, weil sich das Programm beendet hat.

Nun, bei Gemini-7 war gerade  die nicht beendbare Lagesteuerung das 
Problem, das fast zum Exitus der beiden Astronauten geführt hätte.


https://youtu.be/vRKnl0FCEgI?t=25

Und der Iwan denkt auch nicht ans aufhören sondern feuert bis der Tank 
leer ist. Lass doch den Rest der Welt heulen und fordern, dass irgendwer 
immer die eine Steuermöglichkeit haben muß, wer im Funkschatten sitzt, 
sitzt am ruhigsten:

https://www.heise.de/news/Missgluecktes-Andockmanoever-Modul-Nauka-hat-ISS-anderthalbmal-gedreht-6154550.html

https://www.heise.de/news/Nach-Panne-auf-ISS-Russland-nennt-Software-Problem-als-Ursache-6152224.html

Und wenn sich ein Unterprogramm unerwartet beendet, kann es immer noch 
von einem Master(-programm) neugestartet werden. Eine unendliche 
Schleife bedeudet nun mal kontrolleinschränkung/-verlust für einen 
Supervisor.

von Wilhelm M. (wimalopaan)


Lesenswert?

Yalu X. schrieb:
> Wer also darauf besteht, im Kopf einer Endlosschleife die Bedingung
> "true" hinzuschreiben,

Ich bestehe nicht darauf und habe nicht darauf bestanden: ich habe nur 
gesagt, dass for(;;) weniger explizit als while(true) ist. Und da Rolf 
M. nicht weiß, was explizit ist, habe ich geschrieben, dass for(;true;) 
explizit ist, nur um ihm und Dir das klar zu machen. Ich habe nicht 
darauf bestanden, ein true hinzuschreiben.

> der sollte konsequenterweise bei parameterlosen
> Lambda-Ausdrücken die leere Parameterliste hinschreiben.

Nein, beides hat gar nichts miteinander zu tun. Es sind konzeptionell 
unterschiedliche Dinge, die dort passieren.
Das eine ist der Ersatz für einen nicht-vorhandenen Ausdruck, und ein 
Ausdruck liefert einen Wert. Und das andere ist die Möglichkeit, eine 
leere Parameterliste auszudrücken, also kein Ausdruck und damit kein 
Wert. Man kann sich nur darüber unterhalten, ob eine leere 
Parameterliste (leere Menge) oder eine nicht-vorhandene Parameterliste 
(nicht existierende Menge) gleich ist. Da in beiden Fällen kein 
Statement des Blocks des L-Ausdrucks etwas der leeren Menge oder der 
nicht-existierenden Menge referenzieren kann, ist beides aber 
konzeptionell identisch. Es findet auch kein Ersatz durch irgendeinen 
Standardwert statt.

> Wenn du das
> partout ablehnst,

Ich habe das nicht abgelehnt, auch nicht überall.
Du hast das ins Spiel gebracht.

> hat es wenig Sinn, mit dir weiter über Logik in der
> Programmierung zu diskutieren.

Die Texte im C++-Standard sind übrigens (falsch von Dir wiedergegeben, 
Du hast C und C++ Standard vermengt):
1
The for statement
2
for ( init-statement conditionopt ; expressionopt ) statement
3
is equivalent to
4
{
5
init-statement
6
while ( condition ) {
7
statement
8
expression ;
9
}
10
}

und
1
Either or both of the condition and the expression can be omitted. A missing condition makes the implied
2
while clause equivalent to while(true).

von Roland F. (rhf)


Lesenswert?

Hallo,
Wilhelm M. schrieb:
> for ( init-statement conditionopt ; expressionopt ) statement

Da fehlt was.

rhf

von Yalu X. (yalu) (Moderator)


Lesenswert?

Wilhelm M. schrieb:
> Man kann sich nur darüber unterhalten, ob eine leere Parameterliste
> (leere Menge) oder eine nicht-vorhandene Parameterliste (nicht
> existierende Menge) gleich ist.

Natürlich sind das zwei verschiedene Dinge, da muss man sich nicht lange
darüber unterhalten. Allerdings wird in Lambda-Ausdrücken eine nicht
vorhandene Parameterliste gleich behandelt wie eine leere. Ebenso wird
eine nicht vorhandene Bedingung in einer for-Anweisung gleich behandelt
wie eine immer erfüllte.

Ob das optionale Ding ein Ausdruck oder eine Parameterliste ist, macht
meiner Meinung nach für Diskussion, die wir hier führen, keinen
Unterschied. Für beide gilt: Entweder man schreibt es explizit hin, oder
man lässt es weg, dann wird es implizit festgelegt.

Wilhelm M. schrieb:
> Die Texte im C++-Standard sind übrigens (falsch von Dir wiedergegeben,
> Du hast C und C++ Standard vermengt):

Das Thread-Thema ist for(;;) in C:

Jan S. schrieb:
> for(;;){} Schleife
> Guten Tag,
> habe diese Schleife in einer älteren C-Firmware von Pic-Microchip
> gesehen

Deswegen habe ich dafür den C-Standard herangezogen.

Die Lambda-Ausdrücke, die du ins Spiel gebracht hast, gibt es aber nur
in C++, deswegen habe ich dort den C++-Standard zitiert.

Ich hätte natürlich auch für for(;;) den C++-Standard zitieren können.
Da sich dort der entsprechende Satz vom C-Standard nur in der
Formulierung, nicht aber in seiner Aussage unterscheidet, hätte dies an
meiner Argumentation nichts geändert.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Roland F. schrieb:
> Wilhelm M. schrieb:
>> for ( init-statement conditionopt ; expressionopt ) statement
>
> Da fehlt was.

Falls du das Semikolon meinst: Das ist bereits im init-statement
enthalten.

von Rolf M. (rmagnus)


Lesenswert?

Wilhelm M. schrieb:
> Man kann sich nur darüber unterhalten, ob eine leere
> Parameterliste (leere Menge) oder eine nicht-vorhandene Parameterliste
> (nicht existierende Menge) gleich ist.

Natürlich sind sie unterschiedlich. Eine Funktion braucht immer eine 
Parameterliste. Diese kann leer sein. Im Falle von Lambdas (und nur 
dort) hat man eben entschieden, dass sie nicht angegeben werden muss und 
dass das exakt so behandelt wird, als hättest du eine leere 
Parameterliste angegeben. Genau das sagt doch auch der von mir zitierte 
Satz aus dem Standard.

Übrigens würde ich eigentlich erwarten, dass du nicht nur () schreibst, 
sondern "explizit" hinschreibst, dass die Parameterliste leer sein soll, 
also (void). Wenn du das weglässt, ist sie ja nur noch implizit leer, 
und explizit ist doch immer besser als implizit.

> Da in beiden Fällen kein
> Statement des Blocks des L-Ausdrucks etwas der leeren Menge oder der
> nicht-existierenden Menge referenzieren kann, ist beides aber
> konzeptionell identisch. Es findet auch kein Ersatz durch irgendeinen
> Standardwert statt.

Der Standardwert ist die leere Liste.

DSGV-Violator schrieb:
> Und wenn sich ein Unterprogramm unerwartet beendet, kann es immer noch
> von einem Master(-programm) neugestartet werden.

Und was, wenn sich mangels Endlosschleife das Master-Programm beendet 
hat?

> Eine unendliche Schleife bedeudet nun mal kontrolleinschränkung/-verlust
> für einen Supervisor.

Wenn es um Software im Sinne von manuell gestarteten Programmen geht und 
seine Ausführung die Möglichkeit blockiert, andere Programme zu starten, 
ja. Auf der anderen Seite stehen µC-Anwendungen, bei denen es essenziell 
ist, dass das Programm als Endlosschleife läuft, denn wenn es sich 
beenden sollte, passiert je nach dem entweder irgendein Blödsinn, der 
Watchdog macht einen Reset des Systems, oder der µC läuft in eine leere 
Fallback-Endlosschleife. In der Regel will man keins davon.
Das gleich gilt letztendlich auch für dein Master-Programm / 
Betriebssystem.

von DSGV-Violator (Gast)


Lesenswert?

> Der Standardwert ist die leere Liste.

Liste ist ein Datentyp, aber keine Anweisung/Conbtrol-Struktur. C kennt 
im Standard keine Liste, höchstens pointer, bitfields und structs als 
komplexere datentypen.

https://de.wikipedia.org/wiki/Liste_(Datenstruktur)

von Yalu X. (yalu) (Moderator)


Lesenswert?

DSGV-Violator schrieb:
>> Der Standardwert ist die leere Liste.
>
> Liste ist ein Datentyp, aber keine Anweisung/Conbtrol-Struktur. C kennt
> im Standard keine Liste, höchstens pointer, bitfields und structs als
> komplexere datentypen.

Du bist genauso ein Wortklauber wie der Wilhelm. Es dürfte doch aus dem
Kontext mehr als klar hervorgehen, dass mit "Liste" die Parameterliste
gemeint ist.

von Daniel A. (daniel-a)


Lesenswert?

DSGV-Violator schrieb:
> Wilhelm M. schrieb:
>> DSGV-Violator schrieb:
>>> Naja, das Dumme ist, das Standard-C in der Praxis keine boolean Werte
>>> wie 'true' kennt.
>>
>> Mindestens seit C99 aber schon.
>
> Nö. Es gibt da schon einen Unterschied zwischen Sprache und
> Standardbibliotheken.

Doch. In stdbool.h gibt es bool, ist als der Typ _Bool definiert. Man 
kann _Bool natürlich auch direkt verwenden.

Seit C23 sind true, false und bool keywords, das heisst man braucht 
stdbool.h und auch _Bool nicht mehr.

bool hat einige interessante Eigenschaften.
1
_Bool b = 0;
2
b++; // Ergebnis der Expression ist 0 zurück, enthält nachher 1
3
b++; // Ergebnis der Expression ist 1, b enthält nachher immer noch 1
4
b = 10; // b enthält nachher 1
5
b--; // Ergebnis der Expression ist 1, b enthält nachher 0
6
b--; // Ergebnis der Expression ist 0, b enthält nachher 1
7
b--; // Ergebnis der Expression ist 1, b enthält nachher 0

Und ja, auch ein Wert vom typ (_Bool){1} gibt es, also ein echtes true, 
das sind nicht simple ints:
1
#include <stdio.h>
2
#include <stdbool.h>
3
4
int main() {
5
    puts(
6
      _Generic((bool){1},
7
        int: "This is an int",
8
        bool: "This is a bool"
9
      )
10
    );
11
    return 0;
12
}
Ausgabe:
1
This is a bool
https://godbolt.org/z/reanfEY3c

von Rolf M. (rmagnus)


Lesenswert?

DSGV-Violator schrieb:
>> Der Standardwert ist die leere Liste.
>
> Liste ist ein Datentyp, aber keine Anweisung/Conbtrol-Struktur. C kennt
> im Standard keine Liste, höchstens pointer, bitfields und structs als
> komplexere datentypen.

Es ging nicht um Datentypen, sondern um Parameterlisten. Und die sind 
selbstverständlich im C-Standard definiert:
********************************
parameter
formal parameter
formal argument (deprecated)
object declared as part of a function declaration or definition that 
acquires a value on entry to the function, or an identifier from the 
comma-separated list bounded by the parentheses immediately following 
the macro name in a function-like macro definition
********************************

: Bearbeitet durch User
von DSGV-Violator (Gast)


Lesenswert?

> Wenn es um Software im Sinne von manuell gestarteten Programmen geht und
> seine Ausführung die Möglichkeit blockiert, andere Programme zu starten,
> ja. Auf der anderen Seite stehen µC-Anwendungen, bei denen es essenziell
> ist, dass das Programm als Endlosschleife läuft, denn wenn es sich
> beenden sollte, passiert je nach dem entweder irgendein Blödsinn, der
> Watchdog macht einen Reset des Systems, oder der µC läuft in eine leere
> Fallback-Endlosschleife. In der Regel will man keins davon.

In Sicherheitskritischen Anwendungen wie Space/Avionic will man aber 
eine "last resort" Signal-Möglichkeit um das System schnell und mit 
definierte Latenz in einem "Safe harbour" Zustand zu bringen. Oder eben 
Reboot.
Und natürlich macht nur ein von einem Blödian designtes System 
"Blödsinn" nach Beendigung einer Schleife. Ein von einem Kompetenten 
Systemdesigner designtes System geht mach programmabarbeitung in einen 
definierten Zsutand ("Power-Down, Hibernate, ...). Falls die Mittel der 
Software dazu nicht ausreichen muß eben die Hardwareabteilung 
entsprechende Abschaltungen (Tri-State, gemeinsames Potential, inert 
state) vorsehen.

Aber wie schon das wording "System" hinweist, geht eine solche 
Betrachtung weit über den Horizont eines niedrig-hierarchischen 
Endlos-C-Schleifen-Programmieres hinaus.

Die NASA hat eben ihren guten Gründe auf in irdischen Massstäben übliche 
Programmierweise zu verzichten respektive als bekannt unsicher zu 
verbieten.

von DSGV-Violator (Gast)


Lesenswert?

> Es ging nicht um Datentypen, sondern um Parameterlisten. Und die sind
> selbstverständlich im C-Standard definiert:
> ********************************
> parameter
> formal parameter
> formal argument (deprecated)
> object declared as part of a function declaration or definition that
> acquires a value on entry to the function, or an identifier from the
> comma-separated list bounded by the parentheses immediately following
> the macro name in a function-like macro definition
> ********************************

Also das hinter dem 'for' in Klammern heisst jetzt "Parameterliste" wie 
bei einem Funktionsaufruf??
Das sind aber nun mal aber im syntax-Sinne keine Parameter sondern 
Anweisungen. Deshalb finden sie sich auch im Code- und nicht im 
Data-segment.

von Bruno V. (bruno_v)


Lesenswert?

Jetzt haben die Väter von C explizit eine kurze und konsistente 
Endlosschleife realisiert und favorisiert ohne andere Konstrukte 
einzuschränken ... und hier wird ernsthaft argumentiert, das nicht zu 
nutzen.

Ein Anfänger weiß nicht, dass i++ äquivalent ist zu i=i+1. Der Code wird 
aber nicht besser, wenn man auf ++ verzichtet.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Bruno V. schrieb:
> und hier wird ernsthaft argumentiert, das nicht zu nutzen.

Ich sehe diese Diskussion auch als nutzlos an. Man kann in C eine 
Endlosschleife auf verschiedene Art und Weise produzieren... na und?

Wenn verschiedene Arten angeboten werden, dann kann man die auch nutzen. 
Ob die eine oder andere "besser" ist, spielt überhaupt keine Rolle. Der 
Compiler erzeugt da ganz emotionslos denselben Code.

Deshalb verstehe ich diesen ganzen Hickhack um Begriffe hier auch nicht. 
Der eine oder andere hier mag sich bitte mal besinnen und sich fragen, 
ob diese kleinkarierte Diskussion überhaupt der Mühe wert ist.

von DSGV-Violator (Gast)


Lesenswert?

Bruno V. schrieb:
> Jetzt haben die Väter von C explizit eine kurze und konsistente
> Endlosschleife realisiert und favorisiert ohne andere Konstrukte
> einzuschränken ... und hier wird ernsthaft argumentiert, das nicht zu
> nutzen.

Weder konsistent noch favourisiert und "kurz" ist bezüglich der 
Forderung nach verständlichen Code auch mehr von Nach- als Vorteil.

Werdet doch endlich mal erwachsen und insestiert nicht, wie es damals 
die "Väter" in Ihre Tontafel ritzten, sondern wie es Euch und Eurer Zeit 
nutzt. Man läuft doch auch nicht mehr in den gleichen Klamotten wie die 
Väter damals ...

Echt, manche haben hier im Forum weniger Selbstbewusstsein, Pragmatismus 
und Autonomiestreben als die Aimish oder ein Haufen Schläfenbelockter 
Talmud-Schüler. SCNR

https://youtu.be/pc04f4w17rM?t=290
https://de.wikipedia.org/wiki/Pragmatismus

Aber eigentlich muss man ja nicht sofort zu einem einstimmigen Fazit 
kommen, manchmal genügt es festzustellen, das manche reifer sind als 
andere aber noch nicht alles Wasser den Nil abwärts geflossen ist ...

> Wenn verschiedene Arten angeboten werden, dann kann man die auch nutzen.

Eben, goto ist hier das beste Angebot um eine eine unbedingte Schleife 
zu schliessen. Aber Goto ist ja böse - hat 'Papa' gesagt.

von Wilhelm M. (wimalopaan)


Lesenswert?

DSGV-Violator schrieb:
> Werdet doch endlich mal erwachsen und fragt nicht wie es damals die
> "Väter" in Ihre Tontafel ritzten, sondern wie es Euch und Eurer Zeit
> nutzt.

Auch wenn ich Dir in diesem Thread fast nirgends zustimme, so ist das 
genau das, was ich hier

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

schonmal als "katholisch" bezeichnet hatte.

Demnächst wird noch gefordert, dass man doch besser zu den "halben" 
Funktionsprototypen im K&R-Stil zurückkehren sollte.

von (prx) A. K. (prx)


Lesenswert?

Bemerkenswert, wie man sich derart ernst und so lange mit einem derart 
lächerlichen Thema befassen kann.

: Bearbeitet durch User
Beitrag #7479423 wurde vom Autor gelöscht.
von DSGV-Violator (Gast)


Lesenswert?

> Auch wenn ich Dir in diesem Thread fast nirgends zustimme, so ist das
> genau das, was ich hier
>
> Beitrag "Re: for(;;){} Schleife"
>
> schonmal als "katholisch" bezeichnet hatte.

Naja statt "Katholisch" sollte man besser "dogmatisch" schreiben. Weil 
auch unter den 74% Nichthatholen in .de gibt es ziemlich viele die zu 
bequem zum selber nachdenken sind. 
https://upload.wikimedia.org/wikipedia/commons/2/2e/Konfessionen_Deutschland_Zensus_2011.png

https://de.wikipedia.org/wiki/Dogma

> Auch wenn ich Dir in diesem Thread fast nirgends zustimme,
Dein Problem, nicht meins.

von MaWin O. (mawin_original)


Lesenswert?

Wilhelm M. schrieb:
> Demnächst wird noch gefordert, dass man doch besser zu den "halben"
> Funktionsprototypen im K&R-Stil zurückkehren sollte.

Ich fordere die komplette Abkehr von dieser kaputten Sprache.

von Daniel A. (daniel-a)


Lesenswert?

Das war noch vor meiner Zeit. Es gibt aber durchaus Situationen, in 
denen ich die alte Schreibweise noch hätte gebrauchen können, wenn es 
sie noch gäbe.
1
// OK:
2
void myfunction(int w, int h, int x[h][w]){}
3
4
// Fehler
5
void myfunction2(int x[h][w], int w, int h){}
6
7
// Fehler, Schreibweise leider nicht mehr erlaubt:
8
void myfunction3(x,w,h)
9
  int w;
10
  int h;
11
  int x[h][w];
12
{}

von Norbert (der_norbert)


Lesenswert?

MaWin O. schrieb:
> Ich fordere die komplette Abkehr von dieser kaputten Sprache.

Das kannst du sehr professionell bewerkstelligen:
Stecke einfach den Kopf in den Sand.

Es gibt ja auch ›gute‹ Programmiersprachen für den Vogel Strauß,
›Scratch‹ fiele mir da ein, oder ›Turtle-Graphics‹

von Rolf M. (rmagnus)


Lesenswert?

DSGV-Violator schrieb:
> Also das hinter dem 'for' in Klammern heisst jetzt "Parameterliste" wie
> bei einem Funktionsaufruf??

Nein, wie kommst du denn darauf?

> Das sind aber nun mal aber im syntax-Sinne keine Parameter sondern
> Anweisungen. Deshalb finden sie sich auch im Code- und nicht im
> Data-segment.

In C gibt es kein Code- oder Data-Segment. Abgesehen davon hat das auch 
rein gar nichts mit Parameterlisten zu tun.

DSGV-Violator schrieb:
> Werdet doch endlich mal erwachsen und insestiert nicht, wie es damals
> die "Väter" in Ihre Tontafel ritzten, sondern wie es Euch und Eurer Zeit
> nutzt. Man läuft doch auch nicht mehr in den gleichen Klamotten wie die
> Väter damals ...

Ich habe das nicht nach den "Vätern" gemacht. Ich wusste nicht einmal, 
dass das im K&R so steht, bevor es hier jemand zitiert hat. Ich habe 
selbst für mich entschieden, dass ich diese Form für Endlosschleifen 
bevorzuge, und zwar primär, weil ich die eigentlich unnütze Bedingung 
nicht angeben muss. Das macht es für mich einfach zur natürlicheren Wahl 
für eine unbedingte Schleife. Ich war dann aber doch sehr erstaunt, als 
Wilhelm das als "an den Haaren herbeigezogen" betitelt hat.

>> Wenn verschiedene Arten angeboten werden, dann kann man die auch nutzen.
>
> Eben, goto ist hier das beste Angebot um eine eine unbedingte Schleife
> zu schliessen. Aber Goto ist ja böse - hat 'Papa' gesagt.

Für Endlosschleifen ist es auch nicht wirklich sinnvoll. Es gibt aber 
sinnvolle Anwendungsfälle von goto, und dort verwende ich es dann auch.

: Bearbeitet durch User
von DSGV-Violator (Gast)


Lesenswert?

> In C gibt es kein Code- oder Data-Segment. Abgesehen davon, hat das auch
> rein gar nichts mit Parameterlisten zu tun.

Doch hat es, Parameter sind Daten und Zuweisungen sind Instruktionen.


>  Ich habe
> selbst für mich entschieden, dass ich diese Form für Endlosschleifen
> bevorzuge,

Neee wie Du das für Dich entscheidest interessiert kein Schwein und kein 
Compiler. Du hast hier garnichts "selbst" zu entscheiden, du hast (wie 
jeder andere auch) korrekten und möglichst verständlichen Syntax zu 
schreiben. Und für viele ist eben eine Ausage wie etwas nicht ist (Eine 
unendliche Schleife ist wie eine Schleife ohne Parametreliste) nicht 
sonderlich erklärend.
Im Hitchhiker und anderer Belletristik  finden sich solche 
Gedankenmuster, die etwas über ihre Nicht-Sein erklären wollen, bspw.: 
"Fliegen heißt Lernen sich auf den Boden zu schmeißen und ihn zu 
verfehlen. Flying is learning how to throw yourself at the ground and 
miss."

> Für Endlosschleifen ist es auch nicht wirklich sinnvoll.
Doch gerade bei Endloschleifen ist das sinnvoll. Weil ja der Sinn (und 
das Compilat) hinter einer "Endlosschleife" der unbedingte Sprung ist. 
Und welches Schlüsselwort hat C für "unbedingten Sprung" vorgesehen? 
Eben, "Goto" .

von Rolf M. (rmagnus)


Lesenswert?

DSGV-Violator schrieb:
>> In C gibt es kein Code- oder Data-Segment. Abgesehen davon, hat das auch
>> rein gar nichts mit Parameterlisten zu tun.
>
> Doch hat es, Parameter sind Daten und Zuweisungen sind Instruktionen.

Parameter landen aber in der Regel in Registern oder auf dem Stack, und 
das true in der Schleifenbedingung ist keine Zuweisung, sondern ein 
Ausdruck, der vom Compiler üblicherweise komplett wegoptimiert wird, 
also nachher meist gar nirgends landet. Das ist aber alles wie gesagt in 
C nicht spezifiziert, sondern komplett vom Compiler abhängig und damit 
in diesem Zusammenhang irrelevant.

>>  Ich habe
>> selbst für mich entschieden, dass ich diese Form für Endlosschleifen
>> bevorzuge,
>
> Neee wie Du das für Dich entscheidest interessiert kein Schwein und kein
> Compiler.

Dass es dem Compiler egal ist, haben wir vor langem bereits 
festgestellt. Und ob es ein "Schwein" interessiert ist mir egal, denn 
für die schreibe ich den Code nicht. Ich schreibe ihn abgesehen vom 
Compiler für Programmierer, die der Sprache zumindest auf einem gewissen 
Grundniveau mächtig sind. Wer nicht mal weiß, wie eine for-Schleife 
funktioniert, soll lieber die Finger davon lassen, bis er es gelernt 
hat.

> Du hast hier garnichts "selbst" zu entscheiden, du hast (wie
> jeder andere auch) korrekten und möglichst verständlichen Syntax zu
> schreiben.

Ich kann sehr wohl entscheiden, wie ich meinen Code schreibe, denn du 
bist nicht die Codepolizei, die mir das verbieten könnte. Und ja, ich 
habe mich dazu entschieden ihn korrekt und möglichst verständlich zu 
schreiben.
for (;;) ist weder inkorrekt, noch unverständlich.

> Und für viele ist eben eine Ausage wie etwas nicht ist (Eine
> unendliche Schleife ist wie eine Schleife ohne Parametreliste) nicht
> sonderlich erklärend.

Das ist wie bei den meisten Stilfragen und wie auch hier schon öfter 
angemerkt wurde, etwas subjektives. Ich finde es klar, lesbar und 
einleuchtend. Das magst du anders sehen, aber das ist dann eben deine 
persönliche Sichtweise, sprich: Du hast für dich entschieden, dass du 
eine andere Schreibweise bevorzugst - oder jemand anders hat das für 
dich entschieden, und du folgst dem nur dogmatisch. Mehr Optionen gibt's 
da nicht.

>> Für Endlosschleifen ist es auch nicht wirklich sinnvoll.
> Doch gerade bei Endloschleifen ist das sinnvoll. Weil ja der Sinn (und
> das Compilat) hinter einer "Endlosschleife" der unbedingte Sprung ist.
> Und welches Schlüsselwort hat C für "unbedingten Sprung" vorgesehen?
> Eben, "Goto" .

Mit der Argumentation kannst du alle Schleifen per goto umsetzen, denn 
mit einem if kannst du dem ja auch eine Bedingung hinzufügen.
Aber eine Schleife wird in C nunmal üblicherweise mit for oder 
(do/)while und einem Codeblock geschrieben. Warum sollte ich davon bei 
einer Endlosschleife abweichen? Das wäre tatsächlich unintuitiv. Ich 
würde aus Gründen der Lesbarkeit generell davon abraten, goto für 
Rückwärtssprünge zu verwenden.

von Yalu X. (yalu) (Moderator)


Lesenswert?

(prx) A. K. schrieb:
> Bemerkenswert, wie man sich derart ernst und so lange mit einem derart
> lächerlichen Thema befassen kann.

Wie so oft in diesem Forum wurde auch in diesem Thread die Frage des TE
schon nach kurzer Zeit korrekt beantwortet, worauf sich eine Diskussion
über angrenzende Themen anschloss, die für einige interessant sein
mögen, für andere nicht.

Wer den Thread nur deswegen öffnet, weil er dasselbe Problem wie der TE
hat und ausschließlich an der Antwort auf die Ursprungsfrage
interessiert ist, kann den Thread schon nach wenigen Minuten wieder
verlassen. Wer an einer weiterführenden Diskussion interessiert ist,
bleibt drin. So kommt letztendlich jeder auf seine Kosten.

In diesem Forum herrscht diesbezüglich eine andere Kultur als bspw. auf
stackoverflow.com, mikrocontroller.net hat aber IMHO auch weder das Ziel
noch die Ressourcen, ein deutschsprachiges stackoverflow.com zu werden.

Dass solche freien Diskussionen auf mikrocontroller.net oft ergebnislos
verlaufen, sollte jedem klar sein, der daran teilnimmt. Ob eine
Diskussion trotz absehbarer Ergebnislosigkeit wenigstens einen
Erkenntnisgewinn liefern kann, muss jeder für sich selbst entscheiden.

Ich persönlich finde die Diskussion hier trotz ihrer Bedeutungslosigkeit
für die Praxis eigentlich recht interessant. Auf der anderen Seite gibt
es hier Threads mit über hundert Teilnehmern und mehreren Tausend
Beiträgen, die für mich völlig irrelevant sind, deren Teilnehmerzahl
aber auf ein großes Interesse bei anderen Leuten schließen lässt. Auch
diese Threads sind für mich völlig in Ordnung, ich schaue dann eben nur
selten oder überhaupt hinein.

von MaWin O. (mawin_original)


Lesenswert?

Rolf M. schrieb:
> for (;;) ist weder inkorrekt, noch unverständlich.

Es ist unverständlich. "Für nichts" ist kein intuitiver Begriff für eine 
Endlosschleife.

von Rolf M. (rmagnus)


Lesenswert?

MaWin O. schrieb:
> Rolf M. schrieb:
>> for (;;) ist weder inkorrekt, noch unverständlich.
>
> Es ist unverständlich. "Für nichts" ist kein intuitiver Begriff für eine
> Endlosschleife.

Und "Während eins" ist besser?

von MaWin O. (mawin_original)


Lesenswert?

Rolf M. schrieb:
> Und "Während eins" ist besser?

Nicht viel.
Deshalb schreibt man ja auch "Während wahr". Bzw "Solange wahr".

von DSGV-Violator (Gast)


Lesenswert?

> Dass es dem Compiler egal ist, haben wir vor langem bereits
> festgestellt. Und ob es ein "Schwein" interessiert ist mir egal, denn
> für die schreibe ich den Code nicht. Ich schreibe ihn abgesehen vom
> Compiler für Programmierer, die der Sprache zumindest auf einem gewissen
> Grundniveau mächtig sind. Wer nicht mal weiß, wie eine for-Schleife
> funktioniert, soll lieber die Finger davon lassen, bis er es gelernt
> hat.

Um aber eine Endlosschleife zu realisieren braucht man keinerlei 
Kenntnisse bzgl des for-Konstruktes. Das zu (;;) verstümmelte 
for-konstrukt funktioniert nur, weil extra noch ein paar Sonder-Regel 
eingeführt worden, um den Parser/Compiler das "Kotzen" bei diese 
unlogischen Notation auszutreiben.

>> Du hast hier garnichts "selbst" zu entscheiden, du hast (wie
>> jeder andere auch) korrekten und möglichst verständlichen Syntax zu
>> schreiben.
>
> Ich kann sehr wohl entscheiden, wie ich meinen Code schreibe, denn du
> bist nicht die Codepolizei, die mir das verbieten könnte. Und ja, ich
> habe mich dazu entschieden ihn korrekt und möglichst verständlich zu
> schreiben.
> for (;;) ist weder inkorrekt, noch unverständlich.

Träum weiter, träum tief - bin ich hier im falschen Film?
Da fragt ein TO weil ihm das Konstrukt unbekannt und unverständlich ist. 
Und dann kommt so ein selbstgefälliges Irgendwas daher und behauptet 
ungeniert "Das ist ist nicht unverständlich, das ist verständlich."
Dann kann man nur noch "Kognitive Dissonanz" diagnostizieren:
https://www.bfi-ooe.at/de/blog/warum-wir-uns-selbst-austricksen-ohne-es-zu-merken-kognitive-dissonanz.html

"Verschlimmbesserung" ist auch eine Kulturtechnik, um sich nicht selbst 
die Sinnlosigkeit seiner Existenz eingestehen zu müßen.

> Das ist wie bei den meisten Stilfragen und wie auch hier schon öfter
> angemerkt wurde, etwas subjektives. Ich finde es klar, lesbar und
> einleuchtend. Das magst du anders sehen, aber das ist dann eben deine
> persönliche Sichtweise, sprich: Du hast für dich entschieden, dass du
> eine andere Schreibweise bevorzugst

Nein, das ist keine Frage des sprachlichen Stils, sondern die nach der 
Konstruktion eines mathematischen Formelapperates zur Realisation von 
Algorithmenmaschinen. Eben wie die Turing-maschine. Das "Weglassen" gibt 
es im Mathematischen Sinne nicht, da gibt es nur ein neutrales Element 
um eben eine bijektive Abbildung zwischen symbol und Instruktion-Code zu 
ermöglichen. Ja, ich weiß, die mathematischen Grundlagen interessieren 
einen 0815 Codierschwein wenig. 
https://www.cs.virginia.edu/~robins/Turing_Paper_1936.pdf

> Mit der Argumentation kannst du alle Schleifen per goto umsetzen,

Das ist aber keine Argumentation bezüglich aller Schleifen sondern nur 
um den Spezialfall einer degenerierten, da alle wesentlichen 
Schleifeneigenschaften (Anfangsbedingung, Iterationsanweisung, 
Anfangsbedingung) fehlen respektive nicht gebraucht werden.
Eine " for index in anfangswert bis Endwert-schleife ist also völlig 
"überdimensioniert". Es ist halt so, also ob man zum Brötchenholen um 
die Ecke extra den VW-Bully aus der Garage holt statt den kurzen Gang 
direkt zu erledigen.

von Daniel A. (daniel-a)


Lesenswert?

Am Anfang lernt man for Schleifen meistens so:
1
for(int i=0; i<n; i++)

Man lernt dann, ok, Initialisierung, Bedingung, und was für nach dem 
Durchlauf.

Dass man das erste und letzte leer lassen kann, ist nicht so 
erstaunlich. Es gibt ja auch leere Statements (einfach nur ";"), und 
Parameterlisten von Funktionen kann man auch leer lassen.

Aber an einem Ort,  wo man den Wert eines Ausdrucks braucht, den 
weglassen zu können, wie kommt man dort darauf, das man das kann? Egal 
ob in Zuweisungen, Initialisierungen, Operanden, if Bedingungen, while 
schleifen, Funktionsaufrufen, etc, dort kann man das sonst nie machen.

Die ersten paar Jahre wusste ich nicht, dass man die Bedingungen 
weglassen kann. Es ist nicht logisch. Es ist überraschend, unerwartet, 
ein Spezialfall, den man einfach kennen muss!

Darum ist meine lieblingsendlosschleife immer noch "while(true)"

von Yalu X. (yalu) (Moderator)


Lesenswert?

MaWin O. schrieb:
> Rolf M. schrieb:
>> for (;;) ist weder inkorrekt, noch unverständlich.
>
> Es ist unverständlich. "Für nichts" ist kein intuitiver Begriff für eine
> Endlosschleife.

So zu argumentieren, bringt nichts, denn

Yalu X. schrieb:
> Wer versucht, Programmcode zu verstehen, indem er ihn ins Deutsche
> übersetzt, hat schon von vornherein verloren.

MaWin O. schrieb:
> Deshalb schreibt man ja auch "Während wahr". Bzw "Solange wahr".

Sagst du das auch im normalen Sprachgebrauch so?

Auf was bezieht sich dieses "wahr" bzw. was genau muss wahr sein, damit
die Schleife weiterläuft?

von Wolfgang S. (wolfgang_s278)


Lesenswert?

Endlos ja, aber

beachte : !Flags.MotorRunning

von Gerhard O. (gerhard_)


Lesenswert?

jetzt schütte ich mal mehr Öl ins Feuer um etwas Perspektive zu 
präsentieren;-)

Früher(TM) genügte es bei kommerziellen Programmier Werkzeugen die 
zugehörigen mitgelieferten Handbücher zu studieren und erfuhr genug 
Information um damit in C arbeiten zu können. (KEIL z.B.) Es war in den 
meisten Fällen NICHT notwendig andauernd die Compiler Standards und 
andere "highvoluting" akademischen Unterlagen zu recherchieren. Die 
damaligen Compiler waren auch viel einfacher wie C++ und Abkömmliche. 
Ohne grosse Theorie und langjähriges UNI-Studium konnte also der 
"Gelegenheitsprogrammierer" seine Projekte mit den (gedruckten) 
Unterlagen durchziehen, weil genug Information vorhanden waren. Und ja, 
Internet war damals für die meisten noch nicht zugänglich. 
Kostenpflichtige offizielle Dokumente waren ohnehin für die meisten 
nicht erschwinglich.

Wenn also damals dann die Compiler Doku konstatierte, dass eine 
parameterloses for(;;) wie beschrieben funktionieren soll, dann dachte 
man nicht mehr weiter daran und hielt sich an die Documentation um 
funktionierende Programme schreiben zu können. So einfach war das damals 
und man war effektiv im Job um sein Problem zeitgemaess lösen zu können.

Viele damals waren keine Computer Science Akademiker für die 
"Programmieren" eben hin und wieder nur notwendig war, um ein Problem 
lösen zu können und keine hochgradige Wissenschaft die nur sich selber 
zum Ziel hatte. Viele mußten sich die Computer Programmiersprachen 
selbst beibringen. Die Werkzeuge waren da um deren anfallende Probleme 
lösen zu können. Im Vergleich zu C sind die esoterischen Funktionen von 
C++ ohne ausführliches Studium der Compiler Referenzliteratur 
unleserlich bzw. unverständlich für den nicht-Praktiker. Ein typisches C 
Programm dagegen, war zumindest nach Lesen von K&R und Werkzeug 
Dokumention, wenn gut geschrieben,  meistens vollkommen verständlich. 
Das sollte man heute zum Vergleich nicht vergessen. Die heutige Welt mit 
ihren modernen Sprachen-Produkten wie Java, PHP, Python, Rust, etz. 
spielt in einer total anderen Liga. Die heutigen Programme zeigen 
heutzutage aber oft ein hochgradiges Mass an Sprachen Esoterik und 
Abstraktion, das ohne weiteres Studium nicht mehr ohne Weiteres 
verständlich ist. Ob das wirklich notwendig ist, kann ich nicht 
beurteilen. Aus der Sicht eines Akademikers ist das obige natuerlich 
alles Blasphemie. Aber man sollte berücksichtigen, dass viele Menschen 
sich damit nur so weit befassen wollen, weil sie ein Problem zu lösen 
haben.

Ist nur meine Meinung.

von MaWin O. (mawin_original)


Lesenswert?

Yalu X. schrieb:
> Sagst du das auch im normalen Sprachgebrauch so?

Welche Relevanz hat das für eine Programmiersprache?

> Auf was bezieht sich dieses "wahr" bzw.

Auf nichts. Steht doch da. Sonst hieße es "Solange X wahr".

> was genau muss wahr sein, damit
> die Schleife weiterläuft?

Wahr muss wahr sein.

Gerhard O. schrieb:
> Aber man sollte berücksichtigen, dass viele Menschen
> sich damit nur so weit befassen wollen, weil sie ein Problem zu lösen
> haben.

Einer der Hauptgründe dafür, dass so viel Software so ein Sondermüll 
ist.

von DSGV-Violator (Gast)


Angehängte Dateien:

Lesenswert?

Gerhard O. schrieb:
> um etwas Perspektive zu
> präsentieren;-)

Da gibt es mit Folge 13 aus Season 2 von "BigBangTheory" auch ein 
Beispiel aus der Populärkultur zum korrekten Umgang/Notation mit/von 
Endlosschleifen.

https://youtu.be/7dz-7T9HYic?t=45

Bei Sheldons Freundschaftsalgorithmus scheint eine Endlosschleife 
jegliche soziale Anstrengung ad absurdum zu führen, bis "der Ingenieur 
im Team" das Verfahren mit einem Schleifenzähler, Abbruchbedingung zur 
LOA ( am wenigsten unangenehm - "Least Objectionable Activity") 
entschärft bzw. zu einem Abschluss bringt.


Im Anhang Programmablaufplan mit endlosschleife und debuggt
Man sieht, ohne Abbruchbedingung funktioniert die Show nicht. SCNR ;-)

https://www.myfanbase.de/the-big-bang-theory/episodenguide/?eid=4367

von Rolf M. (rmagnus)


Lesenswert?

DSGV-Violator schrieb:
> Das zu (;;) verstümmelte for-konstrukt funktioniert nur, weil extra noch
> ein paar Sonder-Regel eingeführt worden, um den Parser/Compiler das
> "Kotzen" bei diese unlogischen Notation auszutreiben.

Das ist eine sehr unglückliche Formulierung. Besser: Die Option, eine 
Bedingung wegzulassen ist genau dafür eingeführt worden, um damit 
Schleifen formulieren zu können, für die man keine Bedingung möchte.

> Träum weiter, träum tief - bin ich hier im falschen Film?
> Da fragt ein TO weil ihm das Konstrukt unbekannt und unverständlich ist.

Und wenn morgen einer fragt, was denn das komische * nach dem Typ ist, 
dann benutzt du nie mehr Pointer, weil die unverständlich sind? So ein 
Forum ist nunmal auch dafür gedacht, dass Leute Fragen stellen, weil sie 
noch nicht alle Grundlagen kennen. Aus einer einzelnen Frage lässt sich 
nicht schließen, dass etwas unverständlich ist. Hab ich aber oben 
eigentlich schon mal erwähnt.
Ich bin mir auch ziemlich sicher, dass er es nach der ersten Antwort 
gleich verstanden hat und jetzt für den Rest seines Lebens weiß.

[Beleidigungen entfernt…]

> Nein, das ist keine Frage des sprachlichen Stils,

Na sicher. Die Sprache bietet verschiedene syntaktisch korrekte 
Möglichkeiten, eine Endlosschleife zu formulieren. Semantisch können sie 
als äquivalent angesehen werden, weil das Verhalten des Programms in 
allen Varianten das gleiche sein wird. Welche davon man verwendet, ist 
also selbstverständlich eine Frage des sprachlichen Stils und nichts 
anderes.

>> Mit der Argumentation kannst du alle Schleifen per goto umsetzen,
>
> Das ist aber keine Argumentation bezüglich aller Schleifen sondern nur
> um den Spezialfall einer degenerierten, da alle wesentlichen
> Schleifeneigenschaften (Anfangsbedingung, Iterationsanweisung,
> Anfangsbedingung) fehlen respektive nicht gebraucht werden.

Die grundlegende Eigenschaft einer Schleife ist die Wiederholung. Der 
Rest sind optionale Zusätze, die man manchmal, aber nicht immer braucht.

> Eine " for index in anfangswert bis Endwert-schleife ist also völlig
> "überdimensioniert".

Genau deswegen kann man die drei in diesem Fall überflüssigen Ausdrücke 
ja weglassen, statt sowas wie for(true; true; true) oder derlei 
hinschreiben zu müssen.

MaWin O. schrieb:
>> was genau muss wahr sein, damit
>> die Schleife weiterläuft?
>
> Wahr muss wahr sein.

Und du findest es umgangssprachlich ganz normal, wenn man sagt, dass man 
etwas so lange tut, wie wahr wahr ist?

von DSGV-Violator (Gast)


Lesenswert?

> [Beleidigungen entfernt…]

Nein, da stehen keinen Beleidigungen und da wurde auch nichts 
entfernt...

Das mit der kognitiven Dissonanz, also "Tatsache A" sehen und "Story B" 
erzählen oder die im Link beschriebene Verhaltensweise "Warum wir uns 
selbst austricksen ohne es zu merken" zeigst Du ziemlich oft im thread. 
;-) SCNR

von Yalu X. (yalu) (Moderator)


Lesenswert?

MaWin O. schrieb:
> Yalu X. schrieb:
>> Sagst du das auch im normalen Sprachgebrauch so?
>
> Welche Relevanz hat das für eine Programmiersprache?

Keine. Aber warum schreibst du dann:

MaWin O. schrieb:
> Rolf M. schrieb:
>> for (;;) ist weder inkorrekt, noch unverständlich.
>
> Es ist unverständlich. "Für nichts" ist kein intuitiver Begriff für eine
> Endlosschleife.

Für mich ist "solange wahr" genauso intuitiv oder unintuitiv wie
"für nichts", weil beides kein korrektes Deutsch ist.

MaWin O. schrieb:
>> Auf was bezieht sich dieses "wahr" bzw.
>
> Auf nichts. Steht doch da. Sonst hieße es "Solange X wahr".

Hmm, seltsam. Ich dachte immer, dass sich ein Adjektiv auf ein
Substantiv beziehen muss.

>> was genau muss wahr sein, damit
>> die Schleife weiterläuft?
>
> Wahr muss wahr sein.

Ach so. Wie sieht es dann aus mit while(false)?

Nach deiner Argumentation muss dann falsch falsch sein, damit die
Schleife weiterläuft. Ich würde mal behaupten, dass falsch immer falsch
ist, also könnte nach deiner Argumentation eine Endlosschleife auch mit
while(false) eingeleitet werden.

Was lernen wir daraus?

Man sollte sich bei der Programmierung nie auf die Intuition verlassen.
Für eine Programmiersprache gibt es (im Gegensatz zu natürlichen
Sprachen) eine umfassende Spezifikation sowohl der Syntax als auch der
Semantik, da ist Intuition weder notwendig noch zielführend.

Ich kann deswegen nur wiederholen, was hier schon oft geschrieben wurde:
Wenn ihr ordentlich programmieren wollt, dann besorgt euch ein Buch zur
betreffenden Programmiersprache und arbeitet es von der ersten bis zur
letzten Seite durch. Dann bedarf es keiner fraglichen Hilfsmittel wie
Intuition oder die Übersetzung von Programmkonstrukten in natürliche
Sprache.

Wenn ihr dann Code von anderen vorgesetzt bekommt, ist es völlig
unerheblich, ob dort Endlosschleifen mit for(;;), while(1), while(true)
oder goto formuliert sind, weil ihr alle 4 Varianten versteht.

von MaWin O. (mawin_original)


Lesenswert?

Rolf M. schrieb:
> Und du findest es umgangssprachlich ganz normal, wenn man sagt, dass man
> etwas so lange tut, wie wahr wahr ist?

Wo habe ich das gesagt?

Yalu X. schrieb:
> Für mich ist "solange wahr" genauso intuitiv oder unintuitiv wie
> "für nichts", weil beides kein korrektes Deutsch ist.

Dann kann man die Endlosschleife ja auch quibbelbobbel nennen. Das ist 
nach deiner Logik dann ja genau so gut wie for(;;)
1
quibbelbobbel {
2
   ...
3
}

Yalu X. schrieb:
>> Wahr muss wahr sein.
>
> Ach so. Wie sieht es dann aus mit while(false)?

bricht sofort ab, weil false ganz offensichtlich false ist und nie true 
werden kann.

> Nach deiner Argumentation muss dann falsch falsch sein, damit die
> Schleife weiterläuft.

Hä? Nein. Unsinn.

Yalu X. schrieb:
> Dann bedarf es keiner fraglichen Hilfsmittel wie
> Intuition oder die Übersetzung von Programmkonstrukten in natürliche
> Sprache.

Warum sind die C-Schlüsselwörter dann in Englisch, wenn das doch 
schlecht ist und man stattdessen lieber alles aus einem Buch von Grund 
auf lernen soll?
Man könnte 'if' ja falschverstehen. Lieber 'quappelsack' verwenden.

von DSGV-Violator (Gast)


Lesenswert?

> Wenn ihr dann Code von anderen vorgesetzt bekommt, ist es völlig
> unerheblich, ob dort Endlosschleifen mit for(;;), while(1), while(true)
> oder goto formuliert sind, weil ihr alle 4 Varianten versteht.

Naja, aber verpflichtende Code-Stile wurden doch gerade eingeführt, weil 
eben nicht davon auszugehen ist, das jeder im Team jede syntaktische 
Sonderlocke beherrscht.

Hinzukommt bei Sicherheitsrelevanter Soft wie für Avionik oder 
Medizintechnik, das man die Compiler in ihrer benutzten Version 
zertifizieren muß, also sicherstellen, das bei den benutzten 
Syntax-Gekröse immer das selbe raus kommt. Damit diese Testerei nicht 
ausartet, schränkt man eben die benutzten varianten ein. Also eben 
Projektweit eine Variante eine Schleife zu implementieren und nicht alle 
88 Möglichen. Gern wird auch die Richtung und eine Grenze der Iteration 
vorgegeben, bspw. Down to 0. Das macht auch dem Tester das Leben beim 
Schreiben der corner cases einfacher.

Also eben KISS Prinzip, auch bei der AusWahl der synonymen 
Source-Code-Optionen.

https://en.wikipedia.org/wiki/Programming_style

PS:

Natürlich kann man sich auch vom nerdigen Spass beim Progrrammieren 
leiten lassen. Das führte wohl zu der Vermutung, das Dennis Ritchie und 
Brian Kernighan "C" als Scherz ("Hoax")/Persiflage zu Pascal andachten 
und nie als ernsthaftes Programmiersprache sahen. Sie sollen sich auch 
angeblich entschuldigt haben. ;-)

https://www.cs.cmu.edu/~jbruce/humor/unix_hoax.html

Zitat:
 "We stopped when we got a clean compile on the following syntax:
1
for(;P("\n"),R-;P("|"))for(e=3DC;e-;P("_"+(*u++/8)%2))P("|"+(*u/4)%2);
At one time, we joked about selling this to the Soviets to set their 
computer science progress back 20 or more years. "

von Gerhard O. (gerhard_)


Lesenswert?

MaWin O. schrieb:
> Einer der Hauptgründe dafür, daß so viel Software so ein Sondermüll
> ist.

Es ist aber andrerseits durchaus vorstellbar, daß auch Computer Science 
Nichtakademiker klare und logisch fundierte Praxis Programme erdenken 
können die im Kontext ihrer Tätigkeiten täglich benötigt werden und die 
Doku der eingesetzten Sprache verstanden worden ist.

Auch ist es vorstellbar, daß unzählige Elektronik Ingenieure in der 
Vergangenheit und Gegenwart funktionell erstklassige Produkte mit den in 
der Uni absolvierten Kursen programmieren können. In Fakt, es ist sogar 
vorstellbar, daß viele embedded Produkte der Vergangenheit deswegen 
einwandfrei und zügiger funktionierten und keine Cloudanbindung zu 
häufigen SW Upgrades benötigten.

Böswillige Zungen behaupten auch heute noch, daß embedded Geräte der 
Vergangenheit oft sogar besser funktionierten als viele der 
überzüchteten Sachen der Gegenwart die ohne Anbindung ans Mutterschiff 
und deren fragilen Wolkenbänken nicht mehr richtig oder überhaupt 
funktionieren und ewig zum Neu-Booten brauchen.

Leider sterben die Leute aus, die es besser erlebt haben und man kann 
nicht mehr vergleichen, weil die User der Gegenwart es nicht besser 
erlebt haben.
Ein VCR oder CD-Abspielgerät funktionierte praktisch sofort, während 
sich das DVD Abspielgerät minutenlang plagt um überhaupt 
verwendungsfähig zu werden. Vielleicht gibt es dazu gute Gründe, wer 
weiß, nur versäumen es die Hersteller es zu erklären warum so vieles 
Zeugs lahme Enten sind.

Aber was weiß ich, Fossil der Vergangenheit. der vergleichen kann?

von Rolf M. (rmagnus)


Lesenswert?

MaWin O. schrieb:
> Rolf M. schrieb:
>> Und du findest es umgangssprachlich ganz normal, wenn man sagt, dass man
>> etwas so lange tut, wie wahr wahr ist?
>
> Wo habe ich das gesagt?

Es ergibt sich aus dem von dir geschriebenen. Du meintest, "solange 
wahr" sei intuitiv, und auf die Frage, was denn überhaupt wahr sein 
müsse, weil der Satz unvollständig ist, meintest du:

MaWin O. schrieb:
> Wahr muss wahr sein.

MaWin O. schrieb:
> Yalu X. schrieb:
>> Für mich ist "solange wahr" genauso intuitiv oder unintuitiv wie
>> "für nichts", weil beides kein korrektes Deutsch ist.
>
> Dann kann man die Endlosschleife ja auch quibbelbobbel nennen. Das ist
> nach deiner Logik dann ja genau so gut wie for(;;)

Nur wenn man meint, es müsse unbedingt 1:1 auf gesprochene Sprache 
abbildbar sein. Das scheinst aber nur du so zu sehen. Aber das passt ja 
auch schon für klassische Zählschleifen nicht:
1
for (int i = 0; i < 10; ++i)
Wenn man die einfach 1:1 in gesprochene Sprache übersetzt, kommt in etwa 
sowas raus: "Für erzeuge neuen integer i und initialisiere ihn mit Wert 
0, ist i kleiner als 10? und inkrementiere i."
Das ergibt sprachlich auch nicht viel mehr Sinn. Deiner Argumentation 
nach müsste man dann also for-Schleifen generell komplett umbauen, weil 
sie sonst nicht intuitiv sind.

von MaWin O. (mawin_original)


Lesenswert?

Gerhard O. schrieb:
> Leider sterben die Leute aus, die es besser erlebt haben

Ja? Software war früher besser?

Ich muss dich enttäuschen. Das ist die typische früher-war-alles-besser 
Verzerrung.

Software war früher noch viel beschissener als heute. Aber das heißt 
nicht, dass Software heute gut ist.

Glaubst du nicht? Dann installiere doch nochmal MS-DOS auf einem alten 
Rechner.
Oder Windows 95. Oder spiele nochmal ein Spiel auf einem C64.
Das ist aus heutiger Sicht gesehen sowohl von der UX als auch von der 
Softwarequalität absoluter nuklearer Kernschrott.
Die "gute alte Zeit" gibt es bei Software nicht.
Auch nicht im Embedded-Bereich. Schonmal ein Golf-3-Steuergerät 
ausgelesen?
Oder jedes beliebige andere Gerät mit Firmware drauf aus den 90ern. 
Absoluter Schrott war das aus heutiger Sicht.

von MaWin O. (mawin_original)


Lesenswert?

Rolf M. schrieb:
>> Wo habe ich das gesagt?
>
> Es ergibt sich aus dem von dir geschriebenen. Du meintest, "solange
> wahr" sei intuitiv, und auf die Frage, was denn überhaupt wahr sein
> müsse, weil der Satz unvollständig ist,

Aha. Danke für die Bestätigung, dass ich das gar nicht gesagt habe.

Rolf M. schrieb:
> "Für erzeuge neuen integer i und initialisiere ihn mit Wert
> 0, ist i kleiner als 10? und inkrementiere i."

Nur, wenn man mit dem Klammerbeutel gepudert wurde.
Normale Menschen lesen das als 'for i from 0 to one less than 10'.

Rolf M. schrieb:
> Deiner Argumentation
> nach müsste man dann also for-Schleifen generell komplett umbauen, weil
> sie sonst nicht intuitiv sind.

Das ist in der Tat wahr.
Die C-for-Schleife ist einfach nur veralteter Schrott.
Heute macht man das mit Iteratoren viel intuitiver, lesbarer und 
sicherer.
Die Schrottsprache C beherrscht das aber natürlich nicht.

von Yalu X. (yalu) (Moderator)


Lesenswert?

MaWin O. schrieb:
> Yalu X. schrieb:
>> Für mich ist "solange wahr" genauso intuitiv oder unintuitiv wie
>> "für nichts", weil beides kein korrektes Deutsch ist.
>
> Dann kann man die Endlosschleife ja auch quibbelbobbel nennen. Das ist
> nach deiner Logik dann ja genau so gut wie for(;;)

Nein, meine Argumentation beschränkte sich auf while(true) und for(;;).

MaWin O. schrieb:
>> Nach deiner Argumentation muss dann falsch falsch sein, damit die
>> Schleife weiterläuft.
>
> Hä? Nein. Unsinn.

Möglicherweise habe ich deine Aussage

MaWin O. schrieb:
> Wahr muss wahr sein.

falsch interpretiert. Macht aber nichts, weil das Problem mit der Logik
schon vorher begann weder von dir noch von mir aufgelöst werden konnte:

Yalu X. schrieb:
> MaWin O. schrieb:
>>> Auf was bezieht sich dieses "wahr" bzw.
>>
>> Auf nichts. Steht doch da. Sonst hieße es "Solange X wahr".
>
> Hmm, seltsam. Ich dachte immer, dass sich ein Adjektiv auf ein
> Substantiv beziehen muss.

MaWin O. schrieb:
> Warum sind die C-Schlüsselwörter dann in Englisch, wenn das doch
> schlecht ist und man stattdessen lieber alles aus einem Buch von Grund
> auf lernen soll?

Damit man sie sich besser merken kann, nachdem man einmal ihre
Definition gelsen hat. So etwas nennt man auch Gedächtnisstütze (engl.
Mnemonic) und hat mit Intuition wenig bis gar nichts zu tun.

von MaWin O. (mawin_original)


Lesenswert?

Yalu X. schrieb:
> Damit man sie sich besser merken kann, nachdem man einmal ihre
> Definition gelsen hat. So etwas nennt man auch Gedächtnisstütze (engl.
> Mnemonic) und hat mit Intuition wenig bis gar nichts zu tun.

Achso.
1
bang (x == 1) {
2
  shoot;
3
}

Man muss nur lernen, dass 'bang' eine Bedingungsabfrage ist und 'shoot' 
der Funktionsabbruch.
Intuition ist ja was böses, deshalb sind diese Keywords besser als 'if' 
und 'return'. Die könnte ja jemand falsch verstehen.

von Rolf M. (rmagnus)


Lesenswert?

MaWin O. schrieb:
> Aha. Danke für die Bestätigung, dass ich das gar nicht gesagt habe.

Dann hast du dich wohl nur ungeschickt ausgedrückt, denn so kam es 
rüber.

> Rolf M. schrieb:
>> "Für erzeuge neuen integer i und initialisiere ihn mit Wert
>> 0, ist i kleiner als 10? und inkrementiere i."
>
> Nur, wenn man mit dem Klammerbeutel gepudert wurde.
> Normale Menschen lesen das als 'for i from 0 to one less than 10'.

Ach komm, jetzt machst du dich lächerlich. Erst sprichst du von "für 
nichts" und sagst, das sei doch so unintuitiv, weil du es wörtlich 
nimmst, und jetzt sagst du bei einem anderen Beispiel, dass man das doch 
nur anders lesen muss. Und bei diesem gebe ich dir auch recht.

> Die C-for-Schleife ist einfach nur veralteter Schrott.
> Heute macht man das mit Iteratoren viel intuitiver, lesbarer und
> sicherer.

Die einzige Sprache, die ich kenne, die Zählschleifen mit Iteratoren 
macht, ist Python. Damit könnte man sicherlich auch Endlosschleifen 
machen, aber das wäre dann doch eher ungewöhnlich.

: Bearbeitet durch User
von MaWin O. (mawin_original)


Lesenswert?

Rolf M. schrieb:
> das sei doch so unintuitiv, weil du es wörtlich nimmst

Wie nimmt man 'nichts' denn unwörtlich?
Wenn man 'nichts' als 'ever' interpretieren kann, dann auch als 'never'.
Eine Zählschleife, bei der Werte angegeben sind (also mehr als nichts), 
kann man hingegen nicht ohne diese Werte interpretieren. Nichts kann man 
als alles interpretieren. Das ist der Unterschied.

von MaWin O. (mawin_original)


Lesenswert?

Rolf M. schrieb:
> Die einzige Sprache, die ich kenne, die Zählschleifen mit Iteratoren
> macht, ist Python. Damit könnte man sicherlich auch Endlosschleifen
> machen, aber das wäre dann doch eher ungewöhnlich.

Ganz im Gegenteil. Endlose Generatoren sind ziemlich üblich. Auch in 
Python.

von Yalu X. (yalu) (Moderator)


Lesenswert?

MaWin O. schrieb:
> quibbelbobbel

MaWin O. schrieb:
> bang (x == 1) {
>   shoot;
> }

Wenigstens hast du eine lustige Phantasie :)

von Bruno V. (bruno_v)


Lesenswert?

Yalu X. schrieb:
> Damit man sie sich besser merken kann, nachdem man einmal ihre
> Definition gelsen hat. So etwas nennt man auch Gedächtnisstütze (engl.
> Mnemonic) und hat mit Intuition wenig bis gar nichts zu tun

Jede Fachsprache tut gut daran, der Intuition möglichst zu entsprechen.

while tut das, for oder ++ weniger. Und for(;;) noch weniger. Es 
wiederspricht aber auch nicht wirklich, so dass man es übernehmen kann 
mit den Jahren.

Ein Anfänger muss dann halt einmal nachschlagen. So wie jede 
Operator-Prioritat auch, wenn er kein Lisp-Programm daraus machen will 
;-)

von (prx) A. K. (prx)


Lesenswert?

Bruno V. schrieb:
> Jede Fachsprache tut gut daran, der Intuition möglichst zu entsprechen.

Dummerweise sind die Menschen verschieden, einschliesslich dessen, was 
sie als intuitiv empfinden. Obendrein verändert sich die Intuition mit 
der Beschäftigung mit allerlei Themen, auch sprachfremden.

Wenn du also etwas als nicht intuitiv empfindest, dann kann es sein, 
dass der Schöpfer der Sprache es sehr wohl so sah.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Etwas als intuitiv zu empfinden, verleitet auch dazu, das Lehrbuch zu
früh wegzulegen :)

von MaWin O. (mawin_original)


Lesenswert?

Yalu X. schrieb:
> Etwas als intuitiv zu empfinden, verleitet auch dazu, das Lehrbuch zu
> früh wegzulegen :)

Ja, das wäre äußerst schlimm, wenn Dinge intuitiv funktionieren würden 
und man sich nicht durch furztrockene Bücher quälen müsste.
Schließlich wurde uns früher ja auch nichts geschenkt!
Lehrjahre sind keine Herrenjahre!

von Bruno V. (bruno_v)


Lesenswert?

(prx) A. K. schrieb:
> Wenn du also etwas als nicht intuitiv empfindest, dann kann es sein,
> dass der Schöpfer der Sprache es sehr wohl so sah.

Mmh, ich bin mir nicht sicher, ob Du mich persönlich meinst. Ich finde 
dass die Leute bei C einen guten Job gemacht haben. Mit minimalistischen 
Operatoren und Zucker. Bei Pascal z.B. nehmen häufige Elemente 
(procedure, begin, end) einen großen Raum ein. In Mathematik nicht. Oder 
in geschriebener Sprache, wo das kleinste denkbare Zeichen (der Punkt) 
die wichtigste Bedeutung hat.

von (prx) A. K. (prx)


Lesenswert?

Bruno V. schrieb:
> Mmh, ich bin mir nicht sicher, ob Du mich persönlich meinst.

Nein, das war allgemein.

> Ich finde dass die Leute bei C einen guten Job gemacht haben.

Die Deklarationssyntax empfinde ich als Versuch, etwas intuitiv 
verständlich zu machen, das völlig ins Gegenteil lief. Die ist meinen 
Augen durch ihre Mischung aus Präfix- und Infix-Operatoren zur 
Typentwicklung effektiv kontraintuitiv (pointer to array vs array of 
pointers).

Obendrein ist sie auch noch syntaktisch schlecht aufgehängt, wie sich 
bereits bei den bald nachgereichten typedefs zeigte. Aber da geht's in 
die Grammatik der Sprache, in Parser und Lexer. nicht ins Visuelle.

: Bearbeitet durch User
von DSGV-Violator (Gast)


Lesenswert?

> Mit minimalistischen
> Operatoren und Zucker. Bei Pascal z.B. nehmen häufige Elemente
> (procedure, begin, end) einen großen Raum ein. In Mathematik nicht.

Minimalismus ist scheiße, verwendet comments und macht Euch Freunde.

> Oder
> in geschriebener Sprache, wo das kleinste denkbare Zeichen (der Punkt)
> die wichtigste Bedeutung hat.

Für solche Aussagen sind manche in die Psychatrie geschickt worden ;-).

Stenographie ist auch am Ende: 
https://de.wikipedia.org/wiki/Deutsche_Einheitskurzschrift#/media/Datei:Stenogr_Notiz_(Lothar_Spurzem)_2009-06B.jpg

von Rolf M. (rmagnus)


Lesenswert?

MaWin O. schrieb:
> Rolf M. schrieb:
>> das sei doch so unintuitiv, weil du es wörtlich nimmst
>
> Wie nimmt man 'nichts' denn unwörtlich?

Man kann es an der Stelle als "Keine Bedingung" = "unbedingte 
Schleifenausführung" nehmen. Das würde dann genau dem entsprechen, was C 
draus macht und auch dem einzig sinnvollen, was man da draus machen 
kann.

von (prx) A. K. (prx)


Lesenswert?

DSGV-Violator schrieb:
> Minimalismus ist scheiße, verwendet comments und macht Euch Freunde

Ganz wie im realen Leben. Mathe ist scheiße und isoliert, Laberfächer 
sind angesagt, machen Freunde.

Für jemanden, der mit APL anfing, liegt C jedenfalls nur kurz vor COBOL. 
;-)

: Bearbeitet durch User
von Bruno V. (bruno_v)


Lesenswert?

DSGV-Violator schrieb:
> Minimalismus ist scheiße, verwendet comments und macht Euch Freunde.

Natürliche Sprache wird zum Glück nicht an Universitäten entwickelt (im 
Gegensatz zu manchen Programmiersprachen).

Kein des Lesens kundiger würde "Satzbegin" "Satzende" wollen, wenn er 
die Elegeanz von Majuskel und Punkt kennt. Bei Pascal hat der Herr 
Wirth sich was akademisches für Anfänger überlegt.

von (prx) A. K. (prx)


Lesenswert?

Bruno V. schrieb:
> Bei Pascal hat der Herr
> Wirth sich was akademisches für Anfänger überlegt.

Das schon. Aber der Herr hatte Sinn für Grammatik. Herr Ritchie nicht.

von Gerhard O. (gerhard_)


Lesenswert?

Moin,

Was ihr alle gegen C habt:-)

Ich finde es eigentlich wegen seiner Einfachheit sogar superelegant. 
Ursprünglich sollte C bekanntlich ja nur ein Zwischending zwischen ASM 
und den damaligen existierenden Hochsprachen sein. Ritchie wollte es ja 
hauptsächlich für Betriebssystem Einsatz vorsehen und repräsentierte 
eine massive Erleichterung relativ zu ASM.

Was mich angeht, liebe ich C einfach deswegen, weil es klare 
Formulierungen hat und leicht zu merken ist. Die Fußangeln der Sprache 
muß man natürlich kennen. Aber man kann durchaus mit C effektiv sein. 
Ist halt Geschmackssache.

Seit froh, daß es so viele Alternativen gibt, um mit jener Sprache 
glücklich zu werden, die einem zusagt. Wenn nicht gerade die Firma 
vorschreibt welche Sprache in Frage kommt, ist das eine reine 
persönliche Entscheidung.

C++ und neue verbesserte Ansätze, wie vielleicht Rust, sind ja alle 
recht gut und schön und vermeiden bekannte Schwächen von C/C++, aber 
wirklich notwendig sind sie für einen großen Bereich von uC Anwendungen 
auch nicht unbedingt notgedrungen.

Es ist noch nicht lange her, daß kommerzielle und freie Hersteller 
Werkzeuge nur C konnten. Auch da ging es (manchmal fluchend und 
murmelnd).

Nicht jeder muß in kritischen Bereichen arbeiten. Da ist dann 
gleichgültig was und wie verwendet wird.

C++ und ähnliche neue Sprachstandards sind wegen der extremen 
Flexibilität und Esoterik nur dann einsetzbar, wenn man fortwährend 
damit arbeitet, um alle Eigenschaften der Sprache dauerhaft im 
Gedächtnis zu behalten und benötigen oft Recherche um Unklarheiten zu 
klären. Wer nur gelegentlich programmiert und vielleicht schon betagt 
ist, wird vielleicht mit (vertrauten) C am Ende doch besser fahren. 
Nicht jeder ist ein jugendliches Genie mit perfektem Gedächtnis. Im uC 
Bereich lässt sich fast alles praktisch gut genug in einfacherem C 
erledigen.

Ist C brauchbar? Unbedingt. Gibt es Verbesserungen? Klar. Soll halt 
jeder wählen, was ihm zusagt.

Gerhard

: Bearbeitet durch User
von Norbert (der_norbert)


Lesenswert?

Gerhard O. schrieb:
> Ist C brauchbar? Unbedingt. Gibt es Verbesserungen? Klar. Soll halt
> jeder wählen, was ihm zusagt.

Es wird heutzutage eben sehr gerne gemeckert.
Dabei wird gerne mal vergessen:
C ist vor 'nem halben Jahrhundert entwickelt worden, für Maschinen die 
es vor 'nem halben Jahrhundert gab.

Und heute wird von einer gewissen Gruppe eben gemeckert.
Knapp die eine Hälfte meckert wenn es Anpassungen gibt,
knapp die andere Hälfte meckert wenn es keine Anpassungen gibt.

Der Rest hat gelesen, gelernt, ist auch mal gestolpert, hat weiter geübt 
und schließlich ›C‹ für das was es kann Lieben gelernt.

von (prx) A. K. (prx)


Lesenswert?

Gerhard O. schrieb:
> Was ihr alle gegen C habt:-)

Darf ich es gut kennen, viel genutzt haben, bis hin tief in Compilerbau. 
und trotzdem Aspekte davon kritisieren? Es gibt mehr als nur Schwarz und 
Weiss.

: Bearbeitet durch User
von MaWin O. (mawin_original)


Lesenswert?

Norbert schrieb:
> Knapp die eine Hälfte meckert wenn es Anpassungen gibt,
> knapp die andere Hälfte meckert wenn es keine Anpassungen gibt.

3) Es gehört nicht angepasst, sondern komplett ersetzt.

> Der Rest hat gelesen, gelernt, ist auch mal gestolpert, hat weiter geübt
> und schließlich ›C‹ für das was es kann Lieben gelernt.

Stehst du auf sowas? Ist ja Ok. Aber Knebel und Peitsche sind nichts für 
mich.

von Norbert (der_norbert)


Lesenswert?

MaWin O. schrieb:
> Es gehört nicht angepasst, sondern komplett ersetzt.

Und genau das meine ich mit ›Meckern‹.

Wenn jemand noch nicht einmal ansatzweise diese Programmiersprache zu 
erfassen vermag, dann flugs ab zu ›Scratch‹ oder ›Turtle-Graphics‹

Habe übrigens gerade noch einmal nachgesehen, es besteht in der Tat 
keinerlei Zwang ›C‹ zu nutzen.

Wie so oft sollte man auf den guten alten Wittgenstein hören:
»Wovon man nicht sprechen kann, darüber muss man schweigen.«

von MaWin O. (mawin_original)


Lesenswert?

Norbert schrieb:
> Habe übrigens gerade noch einmal nachgesehen, es besteht in der Tat
> keinerlei Zwang ›C‹ zu nutzen.

Du hast wohl noch nie in einem kommerziellen Projekt mitgearbeitet, 
oder?

> Und genau das meine ich mit ›Meckern‹.

Die Wahrheit tut halt manchmal weh.

von Norbert (der_norbert)


Lesenswert?

MaWin O. schrieb:
> Du hast wohl noch nie in einem kommerziellen Projekt mitgearbeitet,
> oder?

Selbstverständlich nicht, ich werkel' seit vierzig Jahren einfach nur so 
für mich zum Vergnügen im stillen Kämmerlein. ;-)

von Gerhard O. (gerhard_)


Lesenswert?

Moin,

Warum kann man nicht:

"Jedem Tierchen, sein Pläsierchen" gönnen?

Gut. C ist über 50 Jahr und man kennt seine Stärken und Schwächen. Ihre 
Existenz verdankt man bekanntlich der Tatsache, daß man überdrüssig dem 
ASM wurde und eine hardwarenahe Verbesserung suchte. Das Ziel war nie, 
eine Hochsprache zu werden. Für solche Zwecke ist C für uC und andere 
Hardware nahe Aufgaben immer noch gut geeignet. C++ ist aber auch als 
Hochsprache bewertet, wenn es auch mit Einschränkungen als Mittelsprache 
geeignet ist. Irgendwie drängt sich deswegen der hinkende Vergleich 
zwischen Äpfel und Birnen auf. Warum vergleicht ihr andauernd C mit C++ 
und alles andere darüber? Das finde ich falsch. Im geschichtlichen 
Kontext findet C durchaus seinen vorgesehenen Platz.

Meine Sicht als Target Anwendung für C ist hauptsächlich embedded. Da 
fällt C durchaus nicht aus seinem Rahmen und hat immer noch eine 
ausreichende Existenzberechtigung und resultiert in effizienten 
Binärcode.

Als Kapitän eines Schiffes hat er die primäre Verantwortung. Das Gleiche 
gilt für die Design Entscheidungen des Entwicklers. Da er die 
Verantwortung trägt, weiß er dann besser was er tut. Er muß entscheiden, 
wo C++ besser geeignet ist wie C.

Auch wenn ihr Experten mit euren Argumenten in manchen Aspekten recht 
habt, heisst das noch lange nicht, daß andere Lösungsansätze und 
Werkzeugwahl notwendigerweise falsch sein müssen, nur weil ein neues 
farbig angestrichenes Pferd, welches sich erst bewähren muß, im Stall 
steht. Auch ein alter Klepper kann sein Last ausdauernd ziehen.

Warum streiten wir uns überhaupt? Was soll die ganze Besserwisserei? Daß 
die neuesten Produkte der heutigen Zeit angepasst wurden, ist ja 
verständlich und in modernen Anwendungen oft notwendig.

Ihr Entwickler (Kapitäne) habt ja die Entscheidungsgewalt; so nützt sie 
weise. Aber andere wegen ihrer Entscheidung zu kritisieren, fällt 
eigentlich außerhalb ihrer Kompetenz. Man wird meistens gute Gründe für 
Design Entscheidungen haben. Ich habe eben Meine.

Obwohl ich ein bisschen mit C++ herum gespielt habe und mir gewisse 
Aspekte ganz klar nützlich sind, finde ich aber insgesamt, daß es mir im 
Kontext beschränkter uC wenig bringt mich vollkommen gescheit machen zu 
müssen, nur um C++ praktisch im Umfeld des uC benützen zu wollen, ohne 
viel Mühen herauszufinden, wie ressourceneffizient ich sie anwenden muß. 
Bei C und meinen bisherigen Erfahrungen, weiß ich genau, was ich tun muß 
oder nicht. In meinem Alter finde ich es wenig zielführend, unzählige 
Stunden aufwenden zu müssen, nur um in C++ efizient funktionieren zu 
können. Fakt ist, wenn man nicht andauernd das Neue übt, man es bald 
wieder vergisst. So gesehen bin ich mit einer Programmiersprache die ich 
gut kenne doch besser dran.

Man mag das sehen, wie man will. Jeder soll doch so vorgehen wie es ihm 
vernünftig erscheint und tolerant anderen gegenüber sein, die eben 
anders denken und glücklich damit werden. Ich habe überhaupt nichts 
gegen C++, ausser, daß es mir zu viel Zeitaufwand verursacht, um es 
gründlich genug lernen zu können, so dass es mir auch etwas nützt. Ich 
brauche es im Kontext meiner Interessen nicht, und das, sollte genügen.

Was nützt es, Anderen gegenüber abfällig zu sein, nur weil man denkt, 
man weiß es besser. Jeder hat für seine Denkweise und Logik seine 
Gründe. Da sollte man tolerant genug sein, Denkweisen Anderer zu 
respektieren.

Dieser ganze Streit um den Bart der Sprachen, find ich wenig 
zielführend.

Es gibt Leute, die bauen mit einfachsten Werkzeugen ein tolles Holzhaus 
in der Wildnis. Es gibt andere, die brauchen dazu eine Fabrik mit 
Werkzeugpark. Das gilt auch sinngemäß für uC Anwendungen.

Gerhard

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Gerhard O. schrieb:
> Warum kann man nicht:
>
> "Jedem Tierchen, sein Pläsierchen" gönnen?
> ...

TL;DR

Du beklagst einen Stellungskrieg zwischen den C und den C++-Jüngern? 
Normalerweise bin ich ja dafür zuständig, so etwas anzuzetteln ... doch 
aber nicht wirklich hier wegen meiner nur halb-ernst gemeinten 
Vorschläge ala `repeat<>` , etc.???

Trotzdem bin ich der Meinung, dass jeder C-Entwickler von den vielen 
kleinen Goodies aus C++ profitieren kann. Das habe ich hier schon in 
ganz vielen Beiträgen auch beispielhaft unterlegt.

Natürlich sind C und C++ unterschiedliche Programmiersprachen, C ist 
kein Subset von C++, und einige Details sind gefährlich unterschiedlich. 
Trotzdem schätze ich, das 90% der hier besprochenen Projekte mit 
Problemen, einfach als C++ kompiliert werden könnten, und man dann 
langsam ein paar Goodies aus C++ einfügen könnte. Man könnte also 
einfach versuchen, wenig zu ändern und doch viel zu profitieren.

von MaWin O. (mawin_original)


Lesenswert?

Wilhelm M. schrieb:
> Du beklagst einen Stellungskrieg zwischen den C und den C++-Jüngern?

Der ist ganz einfach zu lösen, indem man beide auf den Misthaufen der 
Geschichte wirft.

von Gerhard O. (gerhard_)


Lesenswert?

Wilhelm M. schrieb:
> Gerhard O. schrieb:
>> Warum kann man nicht:
>>
>> "Jedem Tierchen, sein Pläsierchen" gönnen?
>> ...
>
> TL;DR
>
> Du beklagst einen Stellungskrieg zwischen den C und den C++-Jüngern?
> Normalerweise bin ich ja dafür zuständig, so etwas anzuzetteln ... doch
> aber nicht wirklich hier wegen meiner nur halb-ernst gemeinten
> Vorschläge ala `repeat<>` , etc.???
>
> Trotzdem bin ich der Meinung, dass jeder C-Entwickler von den vielen
> kleinen Goodies aus C++ profitieren kann. Das habe ich hier schon in
> ganz vielen Beiträgen auch beispielhaft unterlegt.
>
> Natürlich sind C und C++ unterschiedliche Programmiersprachen, C ist
> kein Subset von C++, und einige Details sind gefährlich unterschiedlich.
> Trotzdem schätze ich, das 90% der hier besprochenen Projekte mit
> Problemen, einfach als C++ kompiliert werden könnten, und man dann
> langsam ein paar Goodies aus C++ einfügen könnte. Man könnte also
> einfach versuchen, wenig zu ändern und doch viel zu profitieren.

Hallo Wilhelm,

Wegen TLDR, naja, ich habe nichts gehen C++ und verwende es auch in 
homöopathischen Dosen, wo es mir nützlich ist und intuitiv genug zum 
merken. However, ich habe keinen wirklichen Grund, mich als 
Gelegenheitsprogrammierer komplett einzuarbeiten, weil ich viele 
kritische Details wieder vergessen würde. Übung macht den Meister; aber 
wenn ich nur alle sechs Monate etwas durchziehe, reicht es doch nicht. 
Ich bin 69 und habe nicht mehr dasselbe Gedächtnis eines Jungspunds. Es 
geht nicht um die Philosophie von C++, sondern um die Praxis in meinem 
Kontext und habe überhaupt keine negative Einstellung C++ gegenüber, ich 
finde es einfach zu spezialisiert in Bezug auf den nächsten Abschnitt.

Ich verwende einige uC Familien diverser Hersteller deren Werkzeuge nur 
C können und habe Gründe gewisse Teile oder Apps zu Portieren. Da müsste 
ich unter GCC C++ geschriebene Teile wieder auf C faktorisieren. Da 
bleibe ich lieber allgemein bei neutralen C wegen der Portabilität um es 
mir nicht anzutun. Ich muß auf meine vorhandenen Werkzeuge Rücksicht 
nehmen. Und PC Entwicklung jache ich nicht. Für embedded reichen mir 
meine Möglichkeiten.

Gerhard

von Gerhard O. (gerhard_)


Lesenswert?

MaWin O. schrieb:
> Wilhelm M. schrieb:
>> Du beklagst einen Stellungskrieg zwischen den C und den C++-Jüngern?
>
> Der ist ganz einfach zu lösen, indem man beide auf den Misthaufen der
> Geschichte wirft.

Nichts für ungut. Aber manche Deiner Kommentare finde ich wenig 
konstruktiv:-)

von Rick (rick)


Lesenswert?

Yalu X. schrieb:
> Ich schreibe ja auch nicht
> y = 3 + 10  x  1 + 0;
Ich schon.

Meist ist es dann irgendwas in der folgenden Form:
1
 y0 = 3 + 10 * x * 1 + 0;
2
 y1 = 3 + 10 * x * 2 + 1;
3
 y2 = 3 + 10 * x * 3 + 0;
4
 y3 = 3 + 10 * x * 4 + 1;
5
 ...
Wichtig ist übersichtlicher Code. (Vor allem für den Fall, das ich da 
selber mal wieder ran muss....)

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


Lesenswert?

Passt halbwegs hierher, denke ich, denn es geht auch um Endlosschleifen. 
:-) Geisterte gerade durch die WG14.

https://research.swtch.com/ub

von DSGV-Violator (Gast)


Lesenswert?

Jörg W. schrieb:
> Passt halbwegs hierher, denke ich, denn es geht auch um Endlosschleifen.
> :-) Geisterte gerade durch die WG14.
>
> https://research.swtch.com/ub

Zusammenfassung:
1
 The rationale, paraphrased, was:
2
3
    It is very difficult to tell if a given loop is infinite.
4
    Infinite loops are rare and typically unintentional.
5
    There are many loop optimizations that are only valid for non-infinite loops.
6
    The performance wins of these optimizations are deemed important.
7
    Some compilers already apply these optimizations, making infinite loops non-portable too.
8
    Therefore, we should declare programs with infinite loops undefined behavior, enabling the optimizations.

also etwa,
 * Ein Code-schnüppsel einer Schleife sieht man schwer an, ob es 
unendlich läuft.
 * Unendliche Schleifen sid selten und meist unbeabsichtigt.
 * Viele Schleifenoptimierung sind nur für endliche Schleifen valide.
 * Diese Schleiefenoptimierungen gelten als wichtig.
 * Einige Compiler benutzen diese Optimierungen, deshalb sind solche 
unendlichen schleifen nicht compiler-unabhängig.
 * Deshal sollten wir Programme mit unendlichen Schleifen zu solchen mit 
"undefined behaviour" deklarieren, um so die Optimierung zu ermöglichen.

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


Lesenswert?

DSGV-Violator schrieb:
> Jörg W. schrieb:
>> Passt halbwegs hierher, denke ich, denn es geht auch um Endlosschleifen.
>> :-) Geisterte gerade durch die WG14.
>>
>> https://research.swtch.com/ub
>
> Zusammenfassung:

Das ist die Zusammenfassung ausschließlich des Hans-Boehm-Papiers (und 
nicht etwa des ganzen Artikels).

: Bearbeitet durch Moderator
von DSGV-Violator (Gast)


Lesenswert?

> Das ist die Zusammenfassung ausschließlich des Hans-Boehm-Papiers (und
> nicht etwa des ganzen Artikels).

Was fehlt den aus dem Artikel zum Thema "unendliche ("for") Schleifen im 
C-Quelltext"?

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


Lesenswert?

Es geht im Artikel halt um einiges mehr, und dieser Thread hier befasst 
sich ja nun auch an vielen Stellen mit (Un-)Schönheiten von C als 
solches. Daher sei die komplette Lektüre jedem angeraten.

Man sollte natürlich immer im Hinterkopf behalten, dass der Artikel 
schlicht eine Meinung einer Person ist. Mit der kann man übereinstimmen 
oder auch nicht.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Jörg W. schrieb:
> Passt halbwegs hierher, denke ich, denn es geht auch um Endlosschleifen.
> :-) Geisterte gerade durch die WG14.
>
> https://research.swtch.com/ub

So wie ich das lese, wird argumentiert alle Endlosschleifen sollen UB 
sein, auch solche, die Seiteneffekte haben.  Jedenfalls wird nicht auf 
Seiteneffekte der ersten Schleife verwiesen.

von Wilhelm M. (wimalopaan)


Lesenswert?

Johann L. schrieb:
> Jörg W. schrieb:
>> Passt halbwegs hierher, denke ich, denn es geht auch um Endlosschleifen.
>> :-) Geisterte gerade durch die WG14.
>>
>> https://research.swtch.com/ub
>
> So wie ich das lese, wird argumentiert alle Endlosschleifen sollen UB
> sein, auch solche, die Seiteneffekte haben.  Jedenfalls wird nicht auf
> Seiteneffekte der ersten Schleife verwiesen.

Das denke ich nicht. Endlosschleifen mit Seiteneffekten sind von der 
Argumentation nicht betroffen, denn Ausgangspunkt war die neue 
Formulierung in 6.8.5p6:
1
An iteration statement that performs no input/output operations,
2
does not access volatile objects, and performs no
3
synchronization or atomic operations in its body, controlling
4
expression, or (in the case of a for statement) its expression-3,
5
may be assumed by the implementation to terminate.

von Markus F. (mfro)


Lesenswert?

Wilhelm M. schrieb:
> may be assumed by the implementation to terminate.

Cool. Bei vielen (den meisten?) Mikrocontroller-Programmen führt 
Terminieren dann wieder in eine Endlosschleife ;)

Beitrag #7483756 wurde vom Autor gelöscht.
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Bei C liest sich das übrigens etwas anders:
1
An iteration statement may be assumed by the implementation to terminate if its controlling
2
expression is not a constant expression200), and none of the following operations are performed in its
3
body, controlling expression or (in the case of a for statement) its expression-3201):
4
(…)

Das heißt also, dass just der hier im Thread genannte Fall, egal ob 
"while(true)", "while(1)" oder "for(;;)" explizit als Endlosschleife 
implementiert werden muss.

von Rolf M. (rmagnus)


Lesenswert?

Also etwa sowas?
1
for(;;)
2
    volatile int i; i  = 42;

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Rolf M. schrieb:
>
1
for(;;)
2
    volatile int i; i  = 42;

Geschweifte Klammern vergessen?
1
$ cat a.c
2
int main ()
3
{
4
    for(;;)
5
        volatile int i; i  = 42;
6
}
7
$ cc a.c
8
a.c: In function ‘main’:
9
a.c:4:9: error: expected expression before ‘volatile’
10
         volatile int i; i  = 42;
11
         ^~~~~~~~

: Bearbeitet durch Moderator
von Sebastian W. (wangnick)


Lesenswert?

Liebe Mitforenten,

ihr enttäuscht mich! Da verhunzt ein Newbie den Namen des lieben Peter 
https://de.m.wikipedia.org/wiki/Peter_Naur, und keiner weist ihn 
zurecht!

LG, Sebastian

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


Lesenswert?

Rolf M. schrieb:
> Also etwa sowas?

Von den fehlenden geschweiften Klammern abgesehen: auch sowas darf nicht 
wegoptimiert werden:
1
  for (;;) {}

(Kann Sinn haben, wenn man anschließend alles in Interrupts, Threads 
etc. werkeln lässt.)

von Rolf M. (rmagnus)


Lesenswert?

Frank M. schrieb:
> Rolf M. schrieb:
>>for(;;)
>     volatile int i; i  = 42;
>
> Geschweifte Klammern vergessen?

Ja.

Jörg W. schrieb:
> Rolf M. schrieb:
>> Also etwa sowas?
>
> Von den fehlenden geschweiften Klammern abgesehen: auch sowas darf nicht
> wegoptimiert werden:
>   for (;;) {}

Ich dachte, das sei die Aussage des obigen Zitats aus dem Standard. Der 
Compiler darf annehmen, dass diese Schleife terminiert (warum auch 
immer) und damit auch z.B. den Code, der danach kommt, ausführen.

von Wilhelm M. (wimalopaan)


Lesenswert?

Seit C11 / C++11 und der Einführung des Memory-Models haben C und C++ 
etwas unterschiedliche Begriffe von forward-progress. Das führt dazu, 
dass endlos-Schleifen ohne Seiteneffekte in C++ UB sind und in C nicht. 
Bei trivialen endlos-Schleifen ist das sogar sichtbar. Ein Beispiel ist 
etwa folgendes:
1
#include <stdio.h>
2
3
int main() {
4
  while (1)
5
    ; 
6
}
7
8
void unreachable() {
9
    printf("xxx\n");  
10
}

Mit clang++ -O2 wird hier "xxx" ausgegeben! Die Schleife wird entfernt 
(UB), es bleibt im ASM das main-label, was dann auf derselbe Adresse wie 
unreachable liegt.

von Rolf M. (rmagnus)


Lesenswert?

Kurios, aber ein sehr schönes Beispiel dafür, was UB bedeuten kann.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Wilhelm M. schrieb:
> Seit C11 / C++11 und der Einführung des Memory-Models haben C und C++
> etwas unterschiedliche Begriffe von forward-progress. Das führt dazu,
> dass endlos-Schleifen ohne Seiteneffekte in C++ UB sind und in C nicht.
> Bei trivialen endlos-Schleifen ist das sogar sichtbar. Ein Beispiel ist
> etwa folgendes:
> ...

Interessant. Gibt es auch ein Beispiel, wo dieser Unterschied zu einem
Vorteil in C++ führt, bspw. in Form einer besseren Optimierung, die in C
nicht möglich ist?

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


Lesenswert?

Rolf M. schrieb:
> Der Compiler darf annehmen, dass diese Schleife terminiert

Nein, denn sie hat einen "constant controlling expression". Nur für 
Schleifen, die das nicht haben und nicht eine der nachfolgenden 
Aktionen ausführen (die ich nicht mit zitiert habe), darf der Compiler 
annehmen, dass sie irgendwann terminieren.

Wilhelm M. schrieb:
> Das führt dazu, dass endlos-Schleifen ohne Seiteneffekte in C++ UB sind
> und in C nicht.

Was im Umkehrschluss heißt, dass C++ für MCUs eigentlich tabu ist, denn 
dort kann eine Endlosschleife ohne (sichtbare) Seiteneffekte essenziell 
sein.

von Wilhelm M. (wimalopaan)


Lesenswert?

Jörg W. schrieb:
> Was im Umkehrschluss heißt, dass C++ für MCUs eigentlich tabu ist, denn
> dort kann eine Endlosschleife ohne (sichtbare) Seiteneffekte essenziell
> sein.

Wer in seinem Code UB verwendet, ist selbst Schuld. Dies ist aber kein 
Problem der Sprache, sondern des Programmierers! Deswegen: natürlich ist 
C++ (genauso wie C) absolut gut für MCU geeignet. Auch in C kann ich UB 
produzieren (ja: nicht durch dieses Konstrukt), aber deswegen die 
Sprache C als ungeeignet abzustempeln, machst Du ja auch nicht.

Formell hat ein C++-Programm, was mit einer leeren Endlos-Schleife 
geschrieben ist, und deswegen ISRs enthalten muss, wenn es irgendetwas 
sinnvolles tun soll, noch ein weiteres Problem: es ist nämlich 
strenggenommen kein valides C++ Programm. Zwar existieren im 
C++-Standard Signal-Handler, die per signal() registriert werden, und 
man könnte sie zu ISTs ähnlich betrachten, aber: ähnlich ist nicht 
gleich im Sinne des Standards.

Also anders herum formuliert: wer also ein C++-Programm durch die 
Verwendung von ISRs als nicht konformes Programm darstellt, der sollte 
schon wissen was er tut, und da ist diese Endlos-Schleife das kleinste 
Problem.

: Bearbeitet durch User
von Bauform B. (bauformb)


Lesenswert?

Wilhelm M. schrieb:
> Jörg W. schrieb:
>> Was im Umkehrschluss heißt, dass C++ für MCUs eigentlich tabu ist, denn
>> dort kann eine Endlosschleife ohne (sichtbare) Seiteneffekte essenziell
>> sein.
>
> Formell hat ein C++-Programm, was mit einer leeren Endlos-Schleife
> geschrieben ist, und deswegen ISRs enthalten muss, wenn es irgendetwas
> sinnvolles zun soll, noch ein weiteres Problem: es ist nämlich
> strenggenommen kein valides C++ Programm.

Eine praktischere Anwendung für eine Endlos-Schleife ist z.B. "warten 
auf den Watchdog Reset". Das kann man auch in einem ansonsten "normalen" 
C++-Programm gebrauchen. Deswegen bleibt das Programm doch valide. Womit 
könnte man so eine Endlos-Schleife norm-konform ersetzen?

von Wilhelm M. (wimalopaan)


Lesenswert?

Bauform B. schrieb:
> Eine praktischere Anwendung für eine Endlos-Schleife ist z.B. "warten
> auf den Watchdog Reset". Das kann man auch in einem ansonsten "normalen"
> C++-Programm gebrauchen. Deswegen bleibt das Programm doch valide. Womit
> könnte man so eine Endlos-Schleife norm-konform ersetzen?

Geht nicht: ein C++-Programm ohne Seiteneffekte ist schlicht invalide.
1
The implementation may assume that any thread will eventually do one of the following:
2
(1.1) — terminate,
3
(1.2) — make a call to a library I/O function,
4
(1.3) — perform an access through a volatile glvalue, or
5
(1.4) — perform a synchronization operation or an atomic operation.

Aber wie gesagt: die Watchdog-Exception oder -Reset ist auch etwas, was 
so im C++-Standard nicht betrachtet wird.

von Wilhelm M. (wimalopaan)


Lesenswert?

Yalu X. schrieb:
> Wilhelm M. schrieb:
>> Seit C11 / C++11 und der Einführung des Memory-Models haben C und C++
>> etwas unterschiedliche Begriffe von forward-progress. Das führt dazu,
>> dass endlos-Schleifen ohne Seiteneffekte in C++ UB sind und in C nicht.
>> Bei trivialen endlos-Schleifen ist das sogar sichtbar. Ein Beispiel ist
>> etwa folgendes:
>> ...
>
> Interessant. Gibt es auch ein Beispiel, wo dieser Unterschied zu einem
> Vorteil in C++ führt, bspw. in Form einer besseren Optimierung, die in C
> nicht möglich ist?

Es ist der Umkehrschluss: wenn Endlos-Schleifen zu einem invaliden 
C++-Programm führen, dann folgt daraus, dass ein valides C++-Programm 
kein Endlos-Schleifen enthält. Sprich: der Compiler kann annehmen, dass 
jede Schleife terminiert! Er muss es nicht mehr beweisen, was ja das 
Halte-Problem wäre ;-)

Und damit kann er bspw. aufeinanderfolgende Schleifen zu einer zusammen 
fassen. Und das ist ein Performance Vorteil (im Paper von H. Boehm war 
ein Beispiel).

von Wilhelm M. (wimalopaan)


Lesenswert?

Wilhelm M. schrieb:
> Es ist der Umkehrschluss: wenn Endlos-Schleifen zu einem invaliden
> C++-Programm führen, dann folgt daraus, dass ein valides C++-Programm
> kein Endlos-Schleifen enthält. Sprich: der Compiler kann annehmen, dass
> jede Schleife terminiert! Er muss es nicht mehr beweisen, was ja das
> Halte-Problem wäre ;-)

Dazu noch ein Beispiel:
1
#include <stdio.h>
2
#include <stdint.h>
3
4
static long collatz_conjecture(long i){
5
    while( i != 1 ){
6
        if ((i % 2) == 0)
7
            i /= 2;
8
        else
9
            i = i*3+1;
10
    }
11
    return i;
12
}
13
14
15
int main() {
16
    return collatz_conjecture(42);
17
}

Der C++-Compiler (g++ -O3) produziert daraus ein simples
1
main:
2
        movl    $1, %eax
3
        ret

Und der C Compiler (gcc -O3):
1
main:
2
        movl    $42, %eax
3
.L7:
4
        testb   $1, %al
5
        jne     .L2
6
        movq    %rax, %rdx
7
        shrq    $63, %rdx
8
        addq    %rdx, %rax
9
        sarq    %rax
10
        cmpq    $1, %rax
11
        jne     .L7
12
        movl    $1, %eax
13
        ret
14
.L2:
15
        leaq    1(%rax,%rax,2), %rdx
16
.L5:
17
        testb   $1, %dl
18
        jne     .L6
19
        movq    %rdx, %rax
20
        shrq    $63, %rax
21
        addq    %rdx, %rax
22
        sarq    %rax
23
        jmp     .L7
24
.L6:
25
        leaq    1(%rdx,%rdx,2), %rdx
26
        jmp     .L5

Hat der C++-Compiler die Collatz-Annahme bewiesen? Wohl kaum. Es nimmt 
einfach an, dass die Schleife bei i == 1 terminiert.

: Bearbeitet durch User
Beitrag #7484365 wurde vom Autor gelöscht.
von Wilhelm M. (wimalopaan)


Lesenswert?

Johann L. schrieb im Beitrag #7484365:
> Die Optimierung zu "return 1" wird aber auch ohne Call aus main
> durchgeführt wenn man vor der Schleife i = 42 setzt.
1
long collatz_conjecture(long i){
2
    while( i != 1 ){
3
        if ((i % 2) == 0)
4
            i /= 2;
5
        else
6
            i = i*3+1;
7
    }
8
    return i;
9
}

wird zu
1
collatz_conjecture(long):
2
        movl    $1, %eax
3
        ret

Vielleicht sieht man es so besser?

von Rolf M. (rmagnus)


Lesenswert?

Johann L. schrieb im Beitrag #7484365:
> Die Optimierung zu "return 1" wird aber auch ohne Call aus main
> durchgeführt wenn man vor der Schleife i = 42 setzt.
>
> Hat also nix mit der zitierten Stelle aus dem C++ Standard zu tun.

Warum? Das ändert doch nichts. Wo die 42 herkommt hat doch nichts damit 
zu tun, dass der Compiler aus dem "i |= 1" im Schleifenkopf 
schlussfolgert, dass die Schleife terminiert und i danach den Wert 1 
hat.

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


Lesenswert?

Wilhelm M. schrieb:
> Wer in seinem Code UB verwendet, ist selbst Schuld.

Nur dass, im Gegensatz zu C++, das analoge C-Programm eben gerade kein 
undefined behaviour zeigt. Dort ist die Endlosschleife mit konstanter 
Schleifenbedingung legal und definiert.

Damit ist es in der Tat ein Problem der verwendeten Sprache – auch ohne 
eine explizite Endlosschleife, wie sie bspw. für Rust genannt worden 
ist.

von Wilhelm M. (wimalopaan)


Lesenswert?

Jörg W. schrieb:
> Damit ist es in der Tat ein Problem der verwendeten Sprache – auch ohne
> eine explizite Endlosschleife, wie sie bspw. für Rust genannt worden
> ist.

Ich weiß ja, dass Du lieber Haskell statt C++ magst. Aber nochmal: wenn 
ein Programmierer nicht auf die Unterschiede zwischen 
Programmiersprachen achtet, und damit in der einen Sprache UB 
produziert, ist das nicht Problem der Sprache, sondern des 
Programmierers.

von Wilhelm M. (wimalopaan)


Lesenswert?

Für die ISR-only Fraktion wäre ggf.
1
int main() {
2
    while(true) {
3
        sleep(); // Seiteneffekt zum Aktivieren über eine Register in der MCU
4
    }
5
}

ein Möglichkeit. In C++ garantiert UB-frei.

Beitrag #7484462 wurde vom Autor gelöscht.
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Wilhelm M. schrieb:
> Ich weiß ja, dass Du lieber Haskell statt C++ magst.Wilhelm M. schrieb:
> In C++ garantiert UB-frei.

Nur, falls nicht gerade jemand sleep irgendwie so definiert hat:
1
#ifndef DEBUG
2
# define sleep() _cpu_sleep()
3
#else
4
/* do not sleep when debugging */
5
# define sleep()
6
#endif

Ich bleibe dabei, dass ich die C++-UB an dieser Stelle für eine eher 
nutzlose und gefährliche Geschichte halte. Da es in C kein UB ist, gibt 
es eigentlich auch keine wirkliche Rechtfertigung dafür.

von Hans H. (loetkolben)


Lesenswert?

Hans H. schrieb:
> Ich schreibe die Endlosschleife immer so:
> do {
>  // many
>  // lines
>  // of
>  // code
> } while (1=1);
>
> denn ich finde die Überraschung muß am Ende kommen.

Weil manche ein fehlendes = moniert haben :), hier eine bessere Version:
1
do
2
  
3
  
4
  {
5
6
7
8
  } 
9
  
10
while (0 == 0 == 0 == 0 == 0 == 0 == 0 == 0 == 0 == 0 == 0 == 0 == 0 == 0 == 0 == 0 == 0 == 0 == 0 == 0);

Da hat man dann auch eine schöne Abreißkante beim Typenraddrucker,
denn der Code danach wird ja nicht ausgeführt.
Oder gerade doch wenn man den obigen Ausführungen folgen sollte...

von Hans H. (loetkolben)


Lesenswert?

Wilhelm M. schrieb:
> Hat der C++-Compiler die Collatz-Annahme bewiesen? Wohl kaum. Es nimmt
> einfach an, dass die Schleife bei i == 1 terminiert.

Kann es sein daß der Compiler einfach erkennt daß die Funktion nur mit 
einer Konstante aufgerufen wird?

Wenn das Argument ein Nutzerinput ist, was dann? Das Microsoft C++ wirft 
die Funktion dann jedenfalls nicht raus.

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Hans H. schrieb:
> Kann es sein daß der Compiler einfach erkennt daß die Funktion nur mit
> einer Konstante aufgerufen wird?

Nein.
Probiere
1
volatile long r;
2
3
int main() {
4
    return collatz_conjecture(r);
5
}

von Yalu X. (yalu) (Moderator)


Lesenswert?

Hier ist noch ein (zugegebenermaßen etwas spezielles) Beispiel, wo die
Behandlung von Endlosschleifen nach dem C-Standard vorteilhaft sein
kann:

Wilhelm M. schrieb:
> long collatz_conjecture(long i){
>   ...

Ein pfiffiger Mathematiker möchte herausfinden, ob in der (unendlichen)
Collatz-Folge mit dem Startwert 42 die 7 vorkommt. Natürlich kann man
auch ohne Computer leicht beweisen, dass dies nicht der Fall ist. Da der
Mathematiker aber möglichst zielgerichtet vorgehen und möglichst wenig
seiner Denkzeit investieren möchte, beschließt er, vorab mit Hilfe des
Computers eine erste Vermutung zu generieren. Er nimmt also das von
Wilhelm gepostete Programm und ersetzt darin die Zeile
1
    while( i != 1 ){

durch
1
    while( i != 7 ){

Er kompiliert das Programm als C-Programm und lässt es maximal 5 min
laufen. Es gibt nun zwei Möglichkeiten:

1. Das Programm terminiert schon vor Ablauf der 5 min. Das lässt sehr
   stark vermuten, dass die 7 in der Folge vorkommt.

2. Das Programm terminiert nach den 5 min noch nicht. Dies lässt
   zumindest erahnen, dass die 7 möglicherweise nicht in der Folge
   enthalten ist.

In beiden Fällen hat er zwar nur eine Vermutung, aber so eine Vermutung
kann bei der anschließenden formalen Beweisführung helfen, Sackgassen zu
vermeiden und damit Denkzeit zu sparen.

Mit C++ funktioniert diese Vorgehensweise wegen des UB nicht so ohne
weiteres. Natürlich kann man in die Schleife irgendeinen Seiteneffekt
(bspw. den Zugriff auf eine volatile-Variable) einbauen. Das macht aber
den Code langsamer, so dass innerhalb der 5 min weniger Iterationen
ausgeführt werden, was wiederum die resultierende Vermutung schwächt.

von Wilhelm M. (wimalopaan)


Lesenswert?

Yalu X. schrieb:
> Hier ist noch ein (zugegebenermaßen etwas spezielles) Beispiel, wo die
> Behandlung von Endlosschleifen nach dem C-Standard vorteilhaft sein
> kann:

Du solltest allerdings bedenken, dass auch bei C der Compiler genau 
diese Optimierung durchführen darf:

Nochmal aus dem C-Standard:
1
An iteration statement may be assumed by the implementation to terminate if its controlling
2
expression is not a constant expression200), and none of the following operations are performed in its
3
body, controlling expression or (in the case of a for statement) its expression-3201):
4
 input/output operations
5
 accessing a volatile object
6
 synchronization or atomic operations.

In meiner obigen Funktion ist genau so eine Iteration drin. Die 
Bedingung ist keine constant-expression und die Berechnung enthält keine 
Seiteneffekte.
Der Compiler nimmt an, dass sie terminiert: für i == 1 in meinem Fall 
oder i == 7 in Deinem Fall. Also hier steht bzgl. der mögl. Optimierung 
kein Unterschied zwischen C und C++. Und der Clang / Clang++ machen das 
auch gleich. Beim GCC schein es ein missing-optimization-bug zu sein.

Daher stimmt Deine obige Aussage nur für einen Compiler, der diese mögl. 
Optimierung nicht nutzt.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Wilhelm M. schrieb:
> Yalu X. schrieb:
>> Hier ist noch ein (zugegebenermaßen etwas spezielles) Beispiel, wo die
>> Behandlung von Endlosschleifen nach dem C-Standard vorteilhaft sein
>> kann:
>
> Du solltest allerdings bedenken, dass auch bei C der Compiler genau
> diese Optimierung durchführen darf:

Stimmt.

Ich bin irrtümlicherweise (und ohne lange darüber nachzudenken) davon
ausgegangen, dass du mit dem Collatz-Beispiel die Unterschiede zwischen
den beiden Standards und nicht nur die Unterschiede zwischen clang++ und
gcc aufzeigen wolltest.

von Wilhelm M. (wimalopaan)


Lesenswert?

Ich denke, die ganze Verwirrung bzw. Unklarheit zwischen WG14 und WG21 
liegt in folgendem:

1) C++ definiert 6.9.2.3 intro.progess was ein Thread (Kontrollfluss) zu 
tun hat. Und da ist in jedem Fall irgendwann einmal einen Seiteneffekt 
auszulösen.

2) C definiert in 6.8.5 Iteration statements
2.1) in Satz 3 wie jede Iteration zu behandeln ist, und
2.2) in Satz 4 den Spezialfall ein Iteration mit nicht-konstanter 
Bedingung ohne Seiteneffekte.

Aus 1) folgt, dass in C++ Endlos-Schleifen ohne Seiteneffekte UB sind 
(nicht-valide), und die Fußnote sagt explizit, dass dieses zu 
Optimierungszwecken genutzt werden kann.

In dem hier gezeigten Beispiel besteht die Optimierung daraus, 
anzunehmen, dass die Schleife auch ohne Beweis terminiert.

Bei der trivialen Endlos-Schleife for(;;) {} kann der Compiler trivial 
beweisen, dass die Schleife nicht terminiert, daher ist sie UB, und darf 
entfernt werden.

Aus 2.2) folgt auch für C wie in C++ die Optimierung der Schleife wie in 
1)

Aus 2.1) folgt allerdings, dass ein triviale Endlos-Schleife for(;;){} 
kein UB ist.

Bis C++03 War in C++ die Formulierung unter 1) nicht drin. Damit war 
auch in C++03 die triviale Endlos-Schleife kein UB.

In C99 war 2.2) nicht drin, damit hatte der C-Compiler diese 
Optimierungsmöglichkeit nicht. Das ist vllt der Grund für den GCC 
missing-optimization-bug.

Es gibt jetzt Bestrebungen (so wie ich das beobachte), die 
Formulierungen zu vereinheitlichen.

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Wilhelm M. schrieb:
> Bei der trivialen Endlos-Schleife for(;;) {} kann der Compiler trivial
> beweisen, dass die Schleife nicht terminiert, daher ist sie UB, und darf
> entfernt werden.

Genau diese Mentalität "ist UB, also darf der Compiler eh machen, was er 
will" ist ja, was das von mir referenzierte Paper insgesamt kritisiert: 
"Prioritize Performance over Correctness".

von Wilhelm M. (wimalopaan)


Lesenswert?

Jörg W. schrieb:
> Wilhelm M. schrieb:
>> Bei der trivialen Endlos-Schleife for(;;) {} kann der Compiler trivial
>> beweisen, dass die Schleife nicht terminiert, daher ist sie UB, und darf
>> entfernt werden.
>
> Genau diese Mentalität "ist UB, also darf der Compiler eh machen, was er
> will" ist ja, was das von mir referenzierte Paper insgesamt kritisiert:
> "Prioritize Performance over Correctness".

Absolut,
und das gilt für beide Sprachen C und C++! (Manchmal in der Diskussion 
hatte ich den Eindruck, dass sei mal wieder nur ein C++ Problem)

von (prx) A. K. (prx)


Lesenswert?

Blöderweise gibt es Endlosschleifen ohne vom Compiler erkennbare 
Nebeneffekte, die diese aber in Hardware haben. Ein Beispiel ist der 
Weg, wie AVRs sich selbst zurücksetzen: Watchdog aktivieren, Interrupts 
ggf deaktivieren, und dann for(;;){}. Wäre dann schon gut, wenn der 
Compiler das nicht wegoptimiert. Ähnlich läuft es bei Programmen, die 
sämtliche Aktivitäten in Interrupts erledigen.

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

(prx) A. K. schrieb:
> Blöderweise gibt es Endlosschleifen ohne vom Compiler erkennbare
> Nebeneffekte, die diese aber in Hardware haben. Ein Beispiel ist der
> Weg, wie AVRs sich selbst zurücksetzen: Watchdog aktivieren, Interrupts
> ggf deaktivieren, und dann for(;;){}.

Den Watchdog aktivieren hat mit der Schleife aber nichts zu tun.

> Wäre dann schon gut, wenn der
> Compiler das nicht wegoptimiert. Ähnlich läuft es bei Programmen, die
> sämtliche Aktivitäten in Interrupts erledigen.

Ja klar, ich hatte oben schon ein Lösung dargestellt.

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


Lesenswert?

Wilhelm M. schrieb:
> Absolut,
> und das gilt für beide Sprachen C und C++!

Dann sind wir ja mal einer Meinung. :-)

> (Manchmal in der Diskussion
> hatte ich den Eindruck, dass sei mal wieder nur ein C++ Problem)

Ist es eher zufällig in diesem ganz speziellen Fall, ansonsten sind sie 
sich ja in vielen sehr ähnlich.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

jetzt habt ihr mich völlig vom Glauben abgebracht. Es hieß immer 
Seiteneffekte sind nicht gut und müssen vermieden werden. Jetzt soll man 
Seiteneffekte einbauen damit es nicht UB ist? Ich komme ehrlich gesagt 
nicht mehr mit.

Das kleinste C/C++ Programm lautet
1
int main()
2
{ }
steht in allen Büchern.

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


Lesenswert?

Das ist aber deshalb inkorrekt, weil es einen Rückgabewert liefern muss, 
jedoch keinen erzeugt.

Das war allerdings jetzt gar nicht das Problem. :-)

von Wilhelm M. (wimalopaan)


Lesenswert?

Veit D. schrieb:
> Das kleinste C/C++ Programm lautetint main()
> { }
> steht in allen Büchern.

Perfekt. Wo ist das Problem?

von Wilhelm M. (wimalopaan)


Lesenswert?

Jörg W. schrieb:
> Das ist aber deshalb inkorrekt, weil es einen Rückgabewert liefern muss,
> jedoch keinen erzeugt.

Nein.
main() ist besonders, dass es implizit 0 zurück gibt.

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


Lesenswert?

Wilhelm M. schrieb:
> Nein.
> main() ist besonders, dass es implizit 0 zurück gibt.

OK, das war mir nicht bewusst.

von Wilhelm M. (wimalopaan)


Lesenswert?

Veit D. schrieb:
> Es hieß immer
> Seiteneffekte sind nicht gut und müssen vermieden werden.

Der Begriff Seiteneffekt ist nicht genau definiert, in diesem Kontext 
bedeutet es eher "observable effect", entsprechend den Aktionen, die die 
Standards erwähnen.

von Wilhelm M. (wimalopaan)


Lesenswert?

Jörg W. schrieb:
> Wilhelm M. schrieb:
>> Nein.
>> main() ist besonders, dass es implizit 0 zurück gibt.
>
> OK, das war mir nicht bewusst.

main() hat auch in C mehrere Signaturen, ist also gewissermaßen implizit 
überladen.

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


Lesenswert?

Wilhelm M. schrieb:
> main() hat auch in C mehrere Signaturen, ist also gewissermaßen implizit
> überladen.

Ja, aber (im hosted environment) geben sie alle "int" zurück, nur die 
Parameterliste kann entweder (void) sein (was in C nicht identisch zur 
leeren Liste in Veits Beispiel ist) oder (int, char **).

von Wilhelm M. (wimalopaan)


Lesenswert?

Jörg W. schrieb:
> Wilhelm M. schrieb:
>> main() hat auch in C mehrere Signaturen, ist also gewissermaßen implizit
>> überladen.
>
> Ja, aber (im hosted environment) geben sie alle "int" zurück,

gehört nicht zur Signatur

> nur die
> Parameterliste kann entweder (void) sein (was in C nicht identisch zur
> leeren Liste in Veits Beispiel ist) oder (int, char **).

... und eine beliebige weitere!

z.B int main(int argc, char *argv[], char *envp[])

Und als freestanding muss es noch nicht mal main() sein.

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Jörg W. schrieb:
> Wilhelm M. schrieb:
>> Nein.
>> main() ist besonders, dass es implizit 0 zurück gibt.
>
> OK, das war mir nicht bewusst.

WIMRE aber erst ab C99.

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


Lesenswert?

Wilhelm M. schrieb:
>> Ja, aber (im hosted environment) geben sie alle "int" zurück,
>
> gehört nicht zur Signatur

Ist aber im Standard vorgeschrieben.

> Und als freestanding muss es noch nicht mal main() sein.

Korrekt, aber freestanding schaltet allerlei Optimierungen ab, die 
Annahmen bezüglich der Standardbibliothek treffen. Bspw. kann der 
Compiler dann "strlen("foo")" nicht mehr einfach durch die Konstante 3 
ersetzen. Daher meide ich das persönlich selbst in Umgebungen, die 
eigentlich den Charakter von "freestanding" haben (wie MCUs).

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Wilhelm M. schrieb:
> Veit D. schrieb:
>> Das kleinste C/C++ Programm lautetint main()
>> { }
>> steht in allen Büchern.
>
> Perfekt. Wo ist das Problem?

Es hat keine Seiteneffekte, ist also UB in C++.  Oder gibt es noch ne 
Regel, dass dieser Fall nicht UB ist?

von Wilhelm M. (wimalopaan)


Lesenswert?

Johann L. schrieb:
> Wilhelm M. schrieb:
>> Veit D. schrieb:
>>> Das kleinste C/C++ Programm lautetint main()
>>> { }
>>> steht in allen Büchern.
>>
>> Perfekt. Wo ist das Problem?
>
> Es hat keine Seiteneffekte, ist also UB in C++.  Oder gibt es noch ne
> Regel, dass dieser Fall nicht UB ist?

Es terminiert.

von (prx) A. K. (prx)


Lesenswert?

Wilhelm M. schrieb:
> Es terminiert.

Spätestens bei Reboot vom Zwangsupdate. ;-)

von Wilhelm M. (wimalopaan)


Lesenswert?

Jörg W. schrieb:
> Korrekt, aber freestanding schaltet allerlei Optimierungen ab, die
> Annahmen bezüglich der Standardbibliothek treffen.

Wo steht das?
Was hat das mit main() zu tun?
Ist das eine vorgeschriebene Optimierung wie bspw. copy-elision oder 
NRVO?

von Hans H. (loetkolben)


Lesenswert?

Wilhelm M. schrieb:
> Hans H. schrieb:
>> Kann es sein daß der Compiler einfach erkennt daß die Funktion nur mit
>> einer Konstante aufgerufen wird?
>
> Nein.
> Probiere
> volatile long r;
> int main() {
>     return collatz_conjecture(r);
> }

Dein Beispiel ist UB, da auf r ohne Initialisierung zugegriffen wird.
Da kann der Compiler machen was er will.

Ich hab mal mit godbolt.org und clang 16.0.0 x86-64 folgendes übersetzen 
lassen:
1
#include <iostream>
2
#include <cstdlib>
3
4
static unsigned long collatz_conjecture(unsigned long i) {
5
  while (i != 1) {
6
    if ((i % 2) == 0)
7
      i /= 2;
8
    else
9
      i = i * 3 + 1;
10
  }
11
  return i;
12
}
13
int main(int argc, const char* argv[])
14
{
15
  if (argc > 1) {
16
    unsigned long l{ strtoul(argv[1], nullptr, 10) };
17
    std::cout << collatz_conjecture(l) << std::endl;
18
  }
19
}
und das Assemblerlisting zeigt daß er die Funktion so implementiert wie 
sie geschrieben steht.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Wilhelm M. schrieb:
> ich hatte oben schon ein Lösung dargestellt.

Ja wie sieht denn eine leere Endlosschleife in C++ nun aus?

Im Standard stehen ja nur Brainfuck-Argumente was nicht geht.

Aber wie geht es denn nun?

z.B. eine lokale volatile Variable zu setzen wäre zwar konform, aber 
absoluter Overkill weil Compiler solche Variablen nicht in Registern 
anlegen sondern im Frame! Man brauch also nicht nur einen Frame, sondern 
falls er nicht wegoptimiert werden kann sogar noch einen Frame-Pointer. 
Beispiel: avr-g++.

Und Dinge wie __asm volatile ("":); sind nicht durch den Standard 
abgedeckt und nicht portabel.

von Wilhelm M. (wimalopaan)


Lesenswert?

Hans H. schrieb:
> und das Assemblerlisting zeigt daß er die Funktion so implementiert wie
> sie geschrieben steht.

-O3 vergessen?

von Wilhelm M. (wimalopaan)


Lesenswert?

Johann L. schrieb:
> Wilhelm M. schrieb:
>> ich hatte oben schon ein Lösung dargestellt.
>
> Ja wie sieht denn eine leere Endlosschleife in C++ nun aus?

Geht nicht, soweit ich weiß (s.o.).

>
> Im Standard stehen ja nur Brainfuck-Argumente was nicht geht.
>
> Aber wie geht es denn nun?
>
> z.B. eine lokale volatile Variable zu setzen wäre zwar konform, aber
> absoluter Overkill weil Compiler solche Variablen nicht in Registern
> anlegen sondern im Frame! Man brauch also nicht nur einen Frame, sondern
> falls er nicht wegoptimiert werden kann sogar noch einen Frame-Pointer.
> Beispiel: avr-g++.
>
> Und Dinge wie __asm volatile ("":); sind nicht durch den Standard
> abgedeckt und nicht portabel.

Das ist es keine "leere" Endlos-Schleife mehr, und sie hat 
Seiteneffekte.

Wie gesagt, würde ich mir nicht so große Gedanken machen, weil auch ISRs 
nicht vom Standard gedeckt sind. Also ein C++-Programm mit ISRs ist 
einfach nicht Standard-konform (s.o. hatte ich schon geschrieben), damit 
erübrigt sich die Frage nach der Schleife.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Wilhelm M. schrieb:
> Johann L. schrieb:
>> Wilhelm M. schrieb:
> Das ist es keine "leere" Endlos-Schleife mehr, und sie hat
> Seiteneffekte.

Jetzt mal Butter bei die Fisch und nicht immer drumrumreden.  Mach's mal 
explizit!  Was kommt am nächsten an wheil(1); ran? Ideralerweise so, 
dass auf Asm-Ebene nur ne leere Schleife bleibt.

> Wie gesagt, würde ich mir nicht so große Gedanken machen, weil auch ISRs
> nicht vom Standard gedeckt sind.

Sind die jetzt auch UB???

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Johann L. schrieb:
> Wilhelm M. schrieb:
>> Johann L. schrieb:
>>> Wilhelm M. schrieb:
>> Das ist es keine "leere" Endlos-Schleife mehr, und sie hat
>> Seiteneffekte.
>
> Jetzt mal Butter bei die Fisch und nicht immer drumrumreden.  Mach's mal
> explizit!

Kannst Du nicht lesen?

>
>> Wie gesagt, würde ich mir nicht so große Gedanken machen, weil auch ISRs
>> nicht vom Standard gedeckt sind.
>
> Sind die jetzt auch UB???

Nein, aber sie existieren einfach nicht.

von Wilhelm M. (wimalopaan)


Lesenswert?

Hans H. schrieb:
> Dein Beispiel ist UB, da auf r ohne Initialisierung zugegriffen wird.

Non-local with static storage

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Wilhelm M. schrieb:
> Johann L. schrieb:
>> Jetzt mal Butter bei die Fisch und nicht immer drumrumreden.  Mach's mal
>> explizit! Was kommt am nächsten an while(1); ran? Ideralerweise so,
>> dass auf Asm-Ebene nur ne leere Schleife bleibt.
>
> Kannst Du nicht lesen?

Doch. Aber ich find's einfach nicht. Nur den Beitrag

Wilhelm M. schrieb:
> Ja klar, ich hatte oben schon ein Lösung dargestellt.

der aber nicht auf die Lösung verweist. Und "oben" sind > 300 Beiträge.

Vielleicht magst du den Beitrag mit der Lösung nochmal verlinken.
Oder zitieren, wird ja nicht mehr als 1 Zeile sein.

von Rolf M. (rmagnus)


Lesenswert?

Wilhelm M. schrieb:
> Bei der trivialen Endlos-Schleife for(;;) {} kann der Compiler trivial
> beweisen, dass die Schleife nicht terminiert, daher ist sie UB, und darf
> entfernt werden.

Das ist aber schon eine interessante Auslegung. Er kann beweisen, dass 
die Schleife nie verlassen wird, und deshalb kann er sie einfach 
rauswerfen. Klar ist das bei UB nicht verboten, aber die Argumentation 
wirkt trotzdem etwas komisch. Denn so macht der Code ja das exakte 
Gegenteil von dem, was jemand, der diese Regel nicht kennt, erwarten 
würde.

Jörg W. schrieb:
> Wilhelm M. schrieb:
>> Nein.
>> main() ist besonders, dass es implizit 0 zurück gibt.
>
> OK, das war mir nicht bewusst.

Ist auch eine eher obskure Regel.

Jörg W. schrieb:
> Korrekt, aber freestanding schaltet allerlei Optimierungen ab, die
> Annahmen bezüglich der Standardbibliothek treffen.

Ich denke, es ist eher umgekehrt: Bei hosted ist dem Compiler explizit 
erlaubt, die Annahme zu treffen, dass sich alle Standardfunktionen genau 
so wie im Standard definiert verhalten und auf der Basis zu optimieren.
Ich wüsste aber nicht, dass es ihm bei freestanding verboten wäre, 
Annahmen über mitgelieferte Funktionen zu treffen.

Hans H. schrieb:
>> volatile long r;
>> int main() {
>>     return collatz_conjecture(r);
>> }
>
> Dein Beispiel ist UB, da auf r ohne Initialisierung zugegriffen wird.
> Da kann der Compiler machen was er will.

Nein. Globale Variablen werden implizit mit 0 bzw. 
default-initialisiert.

Wilhelm M. schrieb:
> Also ein C++-Programm mit ISRs ist einfach nicht Standard-konform (s.o.
> hatte ich schon geschrieben), damit erübrigt sich die Frage nach der
> Schleife.

Das sehe ich anders. Was hab ich davon, zu sagen: "Ja, wegen der ISR ist 
das Programm sowieso nicht konform, also ist auch egal, was bei der 
Schleife passiert". Ich muss auf einem µC halt auch ISRs schreiben, und 
die funktionieren auch wie gewünscht, die Schleife aber auf Grund dieser 
Standard-Regel nicht.

: Bearbeitet durch User
von Hans H. (loetkolben)


Lesenswert?

Wilhelm M. schrieb:
> Hans H. schrieb:
>> und das Assemblerlisting zeigt daß er die Funktion so implementiert wie
>> sie geschrieben steht.
>
> -O3 vergessen?

Tatsächlich, mit -O3 wird es dann auch im clang wegoptimiert, 
kopfkratz...

von Hans H. (loetkolben)


Lesenswert?

Wilhelm M. schrieb:
> Non-local with static storage

Hast Recht wird mit 0 initialisiert..., aber trotzdem konstant. Weil 
ohne Speicheradresse ändert da auch das volatile nichts.

von Rolf M. (rmagnus)


Lesenswert?

Hans H. schrieb:
> Hast Recht wird mit 0 initialisiert..., aber trotzdem konstant.

Und? Ein volatile-Zugriff reicht aus, und das ist einer. Was drin steht 
oder ob sich der Wert ändert, spielt keine Rolle.

> Weil ohne Speicheradresse ändert da auch das volatile nichts.

?

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


Lesenswert?

Wilhelm M. schrieb:
>> Korrekt, aber freestanding schaltet allerlei Optimierungen ab, die
>> Annahmen bezüglich der Standardbibliothek treffen.
>
> Wo steht das?

Annahmen hinsichtlich der Funktionalität der Standardbibliothek sind 
halt einer der Punkte, der für ein hosted environment zutrifft.

"Any library facilities available to a freestanding program, other than 
the
minimal set required by Clause 4, are implementation-defined."

Prinzipiell könnte es für Funktionen wie strlen() noch machbar sein, 
diese bei einem konstanten String zu optimieren (Clause 4 würde das 
meiner Meinung nach gestatten), aber in der Praxis passiert es nicht. 
Compiliere einfach mal mit dem Compiler deiner Wahl mit -ffreestanding 
und -fhosted:
1
#include <string.h>
2
3
int len_of_foo(void) {
4
        return strlen("foo");
5
}

> Was hat das mit main() zu tun?

Dass main() in einem freestanding environment einfach gar nicht 
definiert wird (und nicht einmal existieren muss), während es in einem 
hosted environment halt die beiden genannten Prototypen mit Rückkehrwert 
"int" haben soll (oder eben "implementation-defined").

von Wilhelm M. (wimalopaan)


Lesenswert?

Jörg W. schrieb:
> Wilhelm M. schrieb:
>>> Korrekt, aber freestanding schaltet allerlei Optimierungen ab, die
>>> Annahmen bezüglich der Standardbibliothek treffen.
>>
>> Wo steht das?
>
> Annahmen hinsichtlich der Funktionalität der Standardbibliothek sind
> halt einer der Punkte, der für ein hosted environment zutrifft.

Verstehe ich nicht, etwas verworren.

Alle Funktionen, die im Set der verpflichtenden Funktionen der 
Freestanding Variante vorhanden sein müssen, müssen wie beschreiben 
arbeiten.

Allerdings: <cstring> gehört gar nicht zum Freestanding set.

> "Any library facilities available to a freestanding program, other than
> the
> minimal set required by Clause 4, are implementation-defined."

Genau, Du benutzt etwas, was nicht dazu gehört. Insofern muss sich der 
GCC gar nicht darum kümmern und kann deswegen auch gar keine 
(Frontend)-Optimierungen ausführen.

>> Was hat das mit main() zu tun?
>
> Dass main() in einem freestanding environment einfach gar nicht
> definiert wird (und nicht einmal existieren muss), während es in einem
> hosted environment halt die beiden genannten Prototypen mit Rückkehrwert
> "int" haben soll (oder eben "implementation-defined").

Ja, siehe oben:

Wilhelm M. schrieb:
> Und als freestanding muss es noch nicht mal main() sein.

von Veit D. (devil-elec)


Lesenswert?

Moin,

ich möchte ungern die gesellige Runde stören. Nur verstehe ich aktuell 
gerade nicht warum etwas UB sein soll wenn die gelebte Praxis seit 
Jahrzehnten es genauso programmiert.

int main()
{
  while(1) bzw. for(;;)
  {
     ... sinnvoller Code ...
  }
}

Würde ja bedeuten das entweder der Standard völlig an der Praxis vorbei 
lebt oder der C++ Compiler sich nicht an den Standard hält oder noch 
anders. Sonst wären ja alle Programme für µC UB. Kann ja nicht sein. Das 
meinte ich mit, ich falle vom Glauben ab. Aber keine Sorge ich bin nicht 
gläubig.

von Wilhelm M. (wimalopaan)


Lesenswert?

Wilhelm M. schrieb:
> Allerdings: <cstring> gehört gar nicht zum Freestanding set.

Du kannst aber
1
template<auto N>
2
auto length(const char (&a)[N]) {
3
    return N - 1;
4
}

verwenden.

von Wilhelm M. (wimalopaan)


Lesenswert?

Veit D. schrieb:

> int main()
> {
>   while(1) bzw. for(;;)
>   {
>      ... sinnvoller Code ...
>   }
> }
>
 Das hängt stark davon ab, was ... sinnvoller Code ... ist.

von Gerhard O. (gerhard_)


Lesenswert?

Moin,

Mir schwirrt schon der Kopf. Da war ich jahrzehntelang ein glücklicher 
und zufriedener Programmierer. Dann kamt ihr; ihr, die jetzt meine heile 
Welt in Schutt und Asche gelegt habt und ich mich am Boden zerstört 
vorfinde:-) was nu?

Am Anfang konnte man sich ja nur an die Herstellerhandbücher halten und 
die schwiegen sich über die hier diskutierten Feinheiten völlig aus. Die 
konzentrierten sich eher auf bewährte Programmierpraxis anstatt auf 
graue Theorie in verstaubten Compiler und Sprachenstandards 
herumzustöbern.

Abgesehen davon gelten im embedded Bereich andere Berücksichtigungen um 
im uC Bereich praxisgerecht zu sein. Z.B. ein return für main() hat da 
ja keinen Sinn. In Systemen mit BS, gefordert.

Es funktionierte ja immer wie vorgegeben. Ich befasse mich auschließlich 
mit embedded. Ist es dies alles in 99% aller Anwendungsfälle wert? 
Irgendwie sollte embedded praxisnahe sein.

Gerhard

von Norbert (der_norbert)


Lesenswert?

Habe gerade mal den folgenden Code mit g++ (64bit Linux) und auch 
avr-g++ übersetzt. Sowohl ›while‹ als auch (alternativ) ›for‹ erzeugen 
übrigens präzise den gleichen Assembler-Code.
1
int main(void) {
2
    while (true) {}
3
    //for (;;) {}
4
    return 0;
5
}
Ergebnis:
1
~/tmp$ g++ -Wall -Wextra -pedantic -save-temps -std=c++0x -O3 -o "x" "x.cpp"
2
3
  .file  "x.cpp"
4
  .text
5
  .section  .text.startup,"ax",@progbits
6
  .p2align 4
7
  .globl  main
8
  .type  main, @function
9
main:
10
.LFB0:
11
  .cfi_startproc
12
  .p2align 4,,10
13
  .p2align 3
14
.L2:
15
  jmp  .L2
16
  .cfi_endproc
17
.LFE0:
18
  .size  main, .-main
19
  .ident  "GCC: (Debian 10.2.1-6) 10.2.1 20210110"
20
  .section  .note.GNU-stack,"",@progbits
1
~/tmp$ avr-g++ -Wall -Wextra -pedantic -save-temps -std=c++0x -O3 -o "x" "x.cpp"
2
3
  .file  "x.cpp"
4
__SP_H__ = 0x3e
5
__SP_L__ = 0x3d
6
__SREG__ = 0x3f
7
__tmp_reg__ = 0
8
__zero_reg__ = 1
9
  .section  .text.startup,"ax",@progbits
10
.global  main
11
  .type  main, @function
12
main:
13
/* prologue: function */
14
/* frame size = 0 */
15
/* stack size = 0 */
16
.L__stack_usage = 0
17
.L2:
18
  rjmp .L2
19
  .size  main, .-main
20
  .ident  "GCC: (GNU) 5.4.0"
Was mache ich denn nur falsch, oder besser gefragt, warum funktioniert 
das hier problemlos und zwar ganz genau so wie man es erwarten würde?

von Wilhelm M. (wimalopaan)


Lesenswert?

Norbert schrieb:
> Habe gerade mal den folgenden Code mit g++ (64bit Linux) und auch
> avr-g++

Weil der GCC das so macht. Es besteht keine Pflicht den Code mit UB zu 
entfernen.

von Norbert (der_norbert)


Lesenswert?

Wilhelm M. schrieb:
> Weil der GCC das so macht. Es besteht keine Pflicht den Code mit UB zu
> entfernen.

Aha, interessant. Eine nicht ganz unwichtige Information.

Das heißt andere C++ - Compiler könnten sämtliche ISRs ungefragt weg 
optimieren, weil die ja wohl auch - wie weiter oben zu lesen - UB sind.

Ein - hmmm, sagen wir mal - interessanter Ansatz.

von (prx) A. K. (prx)


Lesenswert?

Wenn ihr im Rahmen der Diskussion schlussendlich feststellt, dass es 
zwar theoretisch möglich ist, nicht-triviale C- oder C++-Programme zu 
schreiben, die ausschliesslich perfekt definiert (und korrekt) arbeiten, 
nicht aber praktisch, dann seid ihr schon dicht in der Realität 
angekommen. ;-)

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

Norbert schrieb:
> Wilhelm M. schrieb:
>> Weil der GCC das so macht. Es besteht keine Pflicht den Code mit UB zu
>> entfernen.
>
> Aha, interessant. Eine nicht ganz unwichtige Information.

UB ist Verhalten, für das der Standard absolut keinerlei Vorgaben macht. 
Es gibt damit grundsätzlich keine Verpflichtung für den Compiler, 
irgendetwas zu tun oder nicht zu tun.

> Das heißt andere C++ - Compiler könnten sämtliche ISRs ungefragt weg
> optimieren, weil die ja wohl auch - wie weiter oben zu lesen - UB sind.

Oben ist ausdrücklich zu lesen, dass sie im Standard schlicht gar nicht 
existieren. Die Compiler-Unterstützung dafür liegt also so oder so 
außerhalb des Standards. Da ISRs oft keine ganz normalen Funktionen 
sind, gibt's gar nicht erst einen Standard-Weg, sie überhaupt zu 
definieren. Und wenn ein Compiler schon eine solche 
nicht-Standard-Erweiterung anbietet, wird er das natürlich so tun, dass 
sie auch brauchbar ist.

Wilhelm M. schrieb:
> Veit D. schrieb:
>
>> int main()
>> {
>>   while(1) bzw. for(;;)
>>   {
>>      ... sinnvoller Code ...
>>   }
>> }
>>
>  Das hängt stark davon ab, was ... sinnvoller Code ... ist.

Es müsste eher ... sinnloser Code ... heißen, denn sobald der Code 
irgendeine reale Auswirkung hat, gilt das nicht mehr.

von (prx) A. K. (prx)


Lesenswert?

Rolf M. schrieb:
> Und wenn ein Compiler schon eine solche
> nicht-Standard-Erweiterung anbietet

Beim Cortex-M sind ISRs normale Funktionen ohne irgendwelche 
Sonderlocken wie Nicht-Standard-Erweiterungen. Damit können die also 
alle weg. ;-)

von Daniel A. (daniel-a)


Lesenswert?

Wilhelm M. schrieb:
> template<auto N>
> auto length(const char (&a)[N]) {
>     return N - 1;
> }

Ist aber nicht das selbe wie strlen.
length("1""\0""2""\0""3""\0\0"); // -> 6
strlen("1""\0""2""\0""3""\0\0"); // -> 1

von Daniel A. (daniel-a)


Lesenswert?

Hier noch eine Variante einer endlos schleife, die Optimierungen 
braucht:
1
#include <stdio.h>
2
3
void loop(){
4
  puts("Hello World!");
5
  return loop();
6
}
7
8
int main() {
9
  loop();
10
}

Ohne Optimierungen läuft der stack irgendwann über, aber mit können 
Compiler daraus eine richtige Schleife machen, dank Tail calls.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Veit D. schrieb:
> Nur verstehe ich aktuell gerade nicht warum etwas UB sein soll
> wenn die gelebte Praxis seit Jahrzehnten es genauso programmiert.

Weil WG21 das so festgelegt hat und seither for(;;){} Undefined 
Behaviour ist.

Was ich vermisse, ist dass der aktualisierte Sprachstandard sowas wie 
Best Practices" nennt, wie das Verhalten des ehemals gültigen Codes mit 
den aktualisierten Mitteln erreicht werden kann.

Und hier im Thread wird auch drumrum geredet; wie so oft.  Es werden 
einem Buzzwords oder Teile des Standards um die Ohren gehauen, aber wie 
genau etwas umgesetzt werden kann... da wird gekniffen.

> int main()
> {
>   while(1) bzw. for(;;)
>   {
>      ... sinnvoller Code ...
>   }
> }
>
> Würde ja bedeuten das entweder der Standard völlig an der Praxis vorbei
> lebt

Wäre nicht das erste mal, dass Bedürfnisse von Bare Metal Plattformen 
ignoriert werden.

Früher[tm] wäre /* Empty Body */ unter "sinnvollen Code" gefallen, weil 
es Anwendungen dafür gibt.  Mit akltellem C++ ist es kein sinnvoller 
Code mehr da UB.

Aber was soll man stattdessen nehmen wenn man den Effekt des alten 
for(;;){} erreichen will?

* Lokale volatile Variable schreiben ist nicht das was ich wollen würde, 
weil das teuer ist (Code-Verbrauch).

* __asm volarile ("":); erzeugt zwar kein Overhead, ist aber nicht 
Portabel und kein Standard-C++.


 oder der C++ Compiler sich nicht an den Standard hält oder noch
> anders. Sonst wären ja alle Programme für µC UB. Kann ja nicht sein. Das
> meinte ich mit, ich falle vom Glauben ab. Aber keine Sorge ich bin nicht
> gläubig.

von Rolf M. (rmagnus)


Lesenswert?

(prx) A. K. schrieb:
> Rolf M. schrieb:
>> Und wenn ein Compiler schon eine solche
>> nicht-Standard-Erweiterung anbietet
>
> Beim Cortex-M sind ISRs normale Funktionen ohne irgendwelche
> Sonderlocken wie Nicht-Standard-Erweiterungen.

Wie werden sie dann aufgerufen? Auch wenn die ISR an sich einfach als 
Standard-Funktion definiert werden muss, muss der Compiler trotzdem 
irgendeine Erweiterung haben, damit sie beim Interrupt auch zur 
Ausführung kommen. Ein Compiler, der sie dann wegoptimiert, wäre zwar in 
der Hinsicht standardkonform, aber für µC-Entwicklung halt nicht zu 
gebrauchen.

Johann L. schrieb:
> * Lokale volatile Variable schreiben ist nicht das was ich wollen würde,
> weil das teuer ist (Code-Verbrauch).

Typischerweise zwei zusätzliche Instruktionen. Wenn die nicht mehr in 
den Flash passen, wirst du eh bald ein Problem haben.

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


Lesenswert?

Rolf M. schrieb:
>> Beim Cortex-M sind ISRs normale Funktionen ohne irgendwelche
>> Sonderlocken wie Nicht-Standard-Erweiterungen.
>
> Wie werden sie dann aufgerufen?

Über die Vektortabelle. Auch diese ist aber ein ganz normales C-Array, 
das lediglich an einer bestimmten Stelle im Speicher stehen muss. 
Cortex-M ist ja explizit so designt worden, dass man keine 
Assembler-Magie mehr benötigt – wenngleich es manche Hersteller 
bevorzugen, den Startup-Code immer noch in Assembler zu meißeln. Bei 
Atmels SAMDxx etc. dagegen ist der Startup-Code in C.

Üblicherweise werden die Funktionen der Vektortabelle zwar jenseits des 
Standards als "weak" deklariert, aber das dient lediglich der 
Bequemlichkeit, dass man auf diese Weise mit einer vorgefertigten 
Tabelle arbeiten kann und nicht jede Applikation ihre eigene selbst 
bauen muss. Technisch könnte man auch alles "pure C" selbst schreiben.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Rolf M. schrieb:
> Wie werden sie [ISRs] dann aufgerufen?

Zum Beispiel indem IRQ-Vektoren initialisiert werden.  Dass IRQ-Vektoren 
mehr oder weniger hart verdrahtet sind wie bei avr-gcc ist eher 
unüblich.  Eher üblich wäre, ne IRQ nen indirekten Sprung zu nem 
Signal-Handler ausführen zu lassen. Und der Handler (bzw. dessen 
Adresse) wird vir dessen Verwendung eben irgendwo eingetragen.

> Auch wenn die ISR an sich einfach als Standard-Funktion definiert
> werden muss, muss der Compiler trotzdem irgendeine Erweiterung haben,
> damit sie beim Interrupt auch zur Ausführung kommen.

Bordmittel reichen aus, z.B. Funktionsadresse irgendwo eintragen. Oder 
<signal.h>.

> Johann L. schrieb:
>> * Lokale volatile Variable schreiben ist nicht das was ich wollen würde,
>> weil das teuer ist (Code-Verbrauch).
>
> Typischerweise zwei zusätzliche Instruktionen. Wenn die nicht mehr in
> den Flash passen, wirst du eh bald ein Problem haben.

Es ist mehr. GCC legt auto volatile Variablen im Frame an, nicht in 
Registern.  Es muss also auch ein Frame allokiert werden und zusäzulich 
ein Frame-Pointer (der nicht wegoptimiert werden kann).

...ok, bei avr-g++ sind's nur 4 Instruktionen mehr, ist jetzt nicht 
super tragisch. Aber es ist einfach auch hässlich, nen Code hinschreiben 
zu müssen der mehr macht als nix.

von Bauform B. (bauformb)


Lesenswert?

Johann L. schrieb:
> Aber was soll man stattdessen nehmen wenn man den Effekt des alten
> for(;;){} erreichen will?

Heutzutage will man Strom sparen, also muss man das der Hardware 
irgendwie sagen. Und schon ist die Schleife nicht mehr leer.

Was uns zum nächsten Problem bringt :) Wenn man dafür kein Bit setzen 
kann, braucht man einen Maschinenbefehl wie WFI. Was sagt der Standard 
denn dazu?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Bauform B. schrieb:
> WFI. Was sagt der Standard denn dazu?

Garnichts.  Im Standard gibt's nix wie WFI, Sleep, SFRs oder "Strom 
sparen".

von Rolf M. (rmagnus)


Lesenswert?

Jörg W. schrieb:
> Rolf M. schrieb:
>>> Beim Cortex-M sind ISRs normale Funktionen ohne irgendwelche
>>> Sonderlocken wie Nicht-Standard-Erweiterungen.
>>
>> Wie werden sie dann aufgerufen?
>
> Über die Vektortabelle. Auch diese ist aber ein ganz normales C-Array,
> das lediglich an einer bestimmten Stelle im Speicher stehen muss.

Das meinte ich nicht. Der Aufruf wird initial nicht durch in C++ 
geschriebenen Code ausgelöst, sondern durch interne Hardware des µC. Und 
damit liegt er außerhalb des Standards.

Johann L. schrieb:
> Bordmittel reichen aus, z.B. Funktionsadresse irgendwo eintragen. Oder
> <signal.h>.

Ein Standard-konformer Compiler kann von einem gewissen Codefluss 
ausgehen. Und da ist es nicht vorgesehen, dass quasi aus dem Nichts 
heraus mitten in der Ausführung spontan irgendeine Funktion aufgerufen 
wird, obwohl an der Stelle im Code kein Funktionsaufruf steht.

>> Typischerweise zwei zusätzliche Instruktionen. Wenn die nicht mehr in
>> den Flash passen, wirst du eh bald ein Problem haben.
>
> Es ist mehr. GCC legt auto volatile Variablen im Frame an, nicht in
> Registern.  Es muss also auch ein Frame allokiert werden und zusäzulich
> ein Frame-Pointer (der nicht wegoptimiert werden kann).

Dann einfach static machen. Braucht dann halt noch ein Byte im RAM, 
dafür keinen Stackframe.

> ...ok, bei avr-g++ sind's nur 4 Instruktionen mehr, ist jetzt nicht
> super tragisch.

Ich habe ein ldi vor und ein std in der Schleife gesehen, zumindest bei 
-Os. Natürlich habe ich aber nicht int, sondern uint8_t genommen. Bei 
-O3 scheint er lustigerweise ein loop-Unrolling zu machen, aber nur wenn 
die Variable nicht static ist.
Mit -O3:
1
main:
2
        push r28
3
        push r29
4
        push __zero_reg__
5
        in r28,__SP_L__
6
        in r29,__SP_H__
7
/* prologue: function */
8
/* frame size = 1 */
9
/* stack size = 3 */
10
.L__stack_usage = 3
11
        ldi r24,lo8(42)
12
.L2:
13
        std Y+1,r24
14
        std Y+1,r24
15
        rjmp .L2
Mit -Os:
1
main:
2
        push r28
3
        push r29
4
        push __zero_reg__
5
        in r28,__SP_L__
6
        in r29,__SP_H__
7
/* prologue: function */
8
/* frame size = 1 */
9
/* stack size = 3 */
10
.L__stack_usage = 3
11
        ldi r24,lo8(42)
12
.L2:
13
        std Y+1,r24
14
        rjmp .L2

> Aber es ist einfach auch hässlich, nen Code hinschreiben zu müssen der
> mehr macht als nix.

Es ist auch schon hässlich, Code hinschreiben zu müssen, dessen einzige 
Aufgabe es ist, eigentlich nichts zu machen.

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Bevor hier manche Schnappatmung bekommen ...

1) Das in C++ for(;;) {} UB ist, heißt nicht, dass dort unbrauchbarer 
Code heraus kommen muss.

2) GCC zeigt, dass man dies offensichtlich erkannt hat, und wohl hier 
einfach die C-Variante übernimmt. Wobei es wohl anders ist, dass hier 
einfach das gleich Backend/Middlend mit derselben Formulierung in der 
RTL gefüttert wird.

3) Was clang++ da macht, ist zwar "legal" und sicher ein schönes 
Schulbeispiel für die Auswirkungen von UB. Allerdings verletzt dies 
eklatant die Regel des least-astonischments.

4) Die WG14 / WG21 arbeiten dran, diese verkorkste Formulierung im C++ 
Standard zu verbessern.

Allerdings würde ich mich mal wirklich dafür interessieren, in welchem 
Projekt (mehr als Küchentisch-Hobby) diese Schleife so vorkommt.

von Wilhelm M. (wimalopaan)


Lesenswert?

Daniel A. schrieb:
> Wilhelm M. schrieb:
>> template<auto N>
>> auto length(const char (&a)[N]) {
>>     return N - 1;
>> }
>
> Ist aber nicht das selbe wie strlen.
> length("1""\0""2""\0""3""\0\0"); // -> 6
> strlen("1""\0""2""\0""3""\0\0"); // -> 1
1
template<auto N>
2
consteval size_t length(const char (&a)[N]) {
3
    for(size_t i = 0; i < N; ++i){
4
        if (a[i] == '\0') return i;
5
    }
6
    return N - 1;
7
}

von Wilhelm M. (wimalopaan)


Lesenswert?

Wilhelm M. schrieb:
> Allerdings würde ich mich mal wirklich dafür interessieren, in welchem
> Projekt (mehr als Küchentisch-Hobby) diese Schleife so vorkommt.

Und außerdem ist es vollkommen egal, mit welchem Unsinn die CPU in der 
Endlos-Schleife Ihre Zeit verbringt.

Also wenn Euch
1
while(true) {
2
    sleep();
3
}

nicht passt, dann nehmt
1
while(true) {
2
    noop();
3
}

Und das noop() könnt ihr nach Eurem Gusto ausgestalten:
1
namespace {
2
    volatile uint8_t dummy;
3
    void noop() {
4
        (void)dummy;
5
    }
6
}

Dadurch wird die Latenz bis zur ISR auch nicht schlechter.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Wilhelm M. schrieb:
> Bevor hier manche Schnappatmung bekommen ...
>
> 1) Das in C++ for(;;) {} UB ist, heißt nicht, dass dort unbrauchbarer
> Code heraus kommen muss.

Doch, der Code ist unbrauchbar weil man sich nicht darauf verlassen 
kann.

Oder verwendest du UB in deinen Projekten, und kontrollierst nach jedem 
Compilerlauf, ob das generierte Assembly noch deinen Wünschen 
entspricht?

> 2) GCC zeigt, dass man dies offensichtlich erkannt hat,

Es zeigt garnix. Insbesondere zeigt es nicht, dass der Code verwendbar 
wäre (da UB).  Es scheint auch kein Schalter (wie etwa für Signed 
Overflow) zu geben, der die alte Semantik von for(;;) herstellt.

> Allerdings würde ich mich mal wirklich dafür interessieren, in welchem
> Projekt (mehr als Küchentisch-Hobby) diese Schleife so vorkommt.

Ein Beispiel hat Andreas schon genannt: Hardware-Reset mittels Watchdog.

Phase 1: Watchdog wird konfiguriert und aktiviert.

Phase 2: Es wird gewartet, bis der Watchdog zuschlägt und einen 
Hardware-Reset triggert. Das kann je nach Hardware ein paar ms oder 
zumindest mehrere µs dauern.

Beispiel 2: Eine Applikation, die all ihre Aufgaben in ISRs erledigt. Am 
Ende von main, nach Konfiguration aller IRQs, steht dann eine leere 
Endlosschleife.

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