Forum: Compiler & IDEs Lesbarer ProgrammCode


von Sven (Gast)


Lesenswert?

Hallo zusammen,

Ich habe einen Programmcode für einen Tiny 84, den ich persönlich 
unleserlich finde. Daraufhin habe ich diesen Modularisiert und gemerkt 
das der Flash Speicher mehr in anspruch genommen wurde und die Zeiten 
nicht mehr passten. Eine andere möglichkeit die mir einfällt ist, den 
Programmcode mittels #define in unterschiedliche Header zu 
Modulariseren, dabei dürfte ich dann ja keinen Verlust beim 
Flashspeicher, etc. haben. Nun meine Frage, ist das nutzen von 
Präprozessordirektiven zum Modularisieren (Lesbarer Code) schlecht, in 
hinblick darauf das eventuell irgendwann andere Kollegen mit diesem Code 
arbeiten?

: Verschoben durch User
von Falk B. (falk)


Lesenswert?

@ Sven (Gast)

>unleserlich finde. Daraufhin habe ich diesen Modularisiert und gemerkt
>das der Flash Speicher mehr in anspruch genommen wurde und die Zeiten
>nicht mehr passten.

Dann hast du falsch modularisiert.

>Eine andere möglichkeit die mir einfällt ist, den
>Programmcode mittels #define in unterschiedliche Header zu
>Modulariseren, dabei dürfte ich dann ja keinen Verlust beim
>Flashspeicher, etc. haben. Nun meine Frage, ist das nutzen von
>Präprozessordirektiven zum Modularisieren (Lesbarer Code) schlecht,

Kommt drauf an. Man kann alles übertreiben und vermurksen. Man sollte 
keine zu komplexen Konstrukte per #define machen, auch mit #define 
Macros sollte man eher sparsam umgehen.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Sven schrieb:
> Daraufhin habe ich diesen Modularisiert und gemerkt das der Flash
> Speicher mehr in anspruch genommen wurde und die Zeiten nicht mehr
> passten.

Das wird dann an dem liegen, was Du "modularisieren" nennst. Was genau 
stellst Du Dir darunter vor? Kannst Du das anhand eines Beispiels 
illustrieren?

> Eine andere möglichkeit die mir einfällt ist, den Programmcode mittels
> #define in unterschiedliche Header zu Modulariseren,

Was aber magst Du damit meinen?

> Nun meine Frage, ist das nutzen von Präprozessordirektiven zum
> Modularisieren (Lesbarer Code) schlecht, in hinblick darauf das
> eventuell irgendwann andere Kollegen mit diesem Code arbeiten?

Da bereits das kaum zu verstehen ist:

Versuch mal anhand eines Beispiels zu zeigen, was Du Dir unter 
"Präprozessordirektiven zum Modularisieren" vorstellst.

von Peter (Gast)


Lesenswert?

Ich verstehe nicht was du mit "mittels #define in unterschiedliche 
Header zu
Modulariseren" meinst.

Modularisieren soll man ja nicht zum Selbstzweck, sondern man sollte 
einfach die Aufgaben eines Projekts sinnvoll in Module einteilen.

Wenn der Speicherplatz nicht kritisch ist, sollte man grundsätzlich ein 
lesbares Programm einem speicherplatzoptimiertem Programm vorziehen.

von bitwurschtler (Gast)


Lesenswert?

Sven schrieb:
> Ich habe einen Programmcode für einen Tiny 84, den ich persönlich
> unleserlich finde. Daraufhin habe ich diesen Modularisiert und gemerkt
> das der Flash Speicher mehr in anspruch genommen wurde und die Zeiten
> nicht mehr passten.

Falsche Ansatz,

der Code braucht kein Facelift, der Code braucht ne Dokumentation.

von Peter D. (peda)


Lesenswert?

Du kannst den GCC zwingen, Funktionen zu inlinen. Ich hab mir dafür ein 
Macro geschrieben:
1
// Always Inline
2
#define AIL(x)          static inline x __attribute__ ((always_inline)); static inline x
3
#define INLINE(x)  AIL(x)

Nur einmal aufgerufene Funktionen sollte er aber automatisch inlinen.
Schau mal ins Assemblerlisting, welcher Code teuer ist.

Persönlich habe ich bei Modularisierung eher den Effekt, daß der Code 
kleiner wird.

von M.A. S. (mse2)


Lesenswert?

Peter schrieb:
> Ich verstehe nicht was du mit "mittels #define in unterschiedliche
> Header zu
> Modulariseren" meinst.

Ich auch nicht, könnte mir aber vorstellen, dass er das mit #include 
verwechselt. (?)
Falls ja, könnte er meinen, sein ehemals großes Source-File in kleine 
Files zu zerlegen und diese dann in einem zu includieren.

Als unwissender Student habe ich das zumindest eine Zeit lang so 
gemacht, bis mir klar wurde, wie man es richtig macht mit dem 
Compilieren und Zusammenlinken unterschiedlicher Sourcen.

: Bearbeitet durch User
von Sven (Gast)


Lesenswert?

bsp:
main()
{
 int a,b, c;
 a =2;
 b=3;
 c = a + b;
}


=>

main()
{
int c;
c = summe(a,b);
}

int summe(int a, int b)
{
 return a + b;
}


=>
main()
{
#SUMME
}

In der Header
#SUMME int a,b, c;\
 a =2;\
 b=3;\
 c = a + b;

von Ich (Gast)


Lesenswert?

Na viel Spaß beim Tippen, debuggen, usw...

von Peter D. (peda)


Lesenswert?

Sven schrieb:
> und die Zeiten
> nicht mehr passten.

Das darf eigentlich nicht passieren. Zeiten macht man mit Timern oder 
_delay_us().
Wenn sie nicht mehr passen, deutet das auf hohen Overhead hin, z.B. 
falscher Optimierungslevel, verschwenderische Verwendung von Pointern 
auf Pointern, unnötig große Datenformate.

: Bearbeitet durch User
von Sven (Gast)


Lesenswert?

Wenn ich doch eine Methode aufrufe werden doch Daten auf den Stack 
geschrieben und eine Sprunganweisung ausgeführt. Wenn ich dagegen den 
Code Sequentiell ausführe, dann benutzt er keine Sprunganweisung und 
muss auch nicht notwendigerweise Daten auf dme Stack schrieben und 
sichern.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Sven schrieb:
> =>
> main()
> {
> #SUMME
> }

Das ist unleserlich, unwartbar und unübersichtlich, also exakt das 
Gegenteil, was Du mit Deiner Modularisierung erreichen willst.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Vielleicht zeigst du uns einfach mal deinen Code (vor und nach deiner 
"Modularisierung")

Peter D. schrieb:
> verschwenderische Verwendung von Pointern
> auf Pointern

Daran hab ich grad ganz ganz große zweifel ;-)

von Nop (Gast)


Lesenswert?

Sven schrieb:

> =>
> main()
> {
> #SUMME
> }
>
> In der Header
> #SUMME int a,b, c;\
>  a =2;\
>  b=3;\
>  c = a + b;

Mit anderen Worten, Du ruinierst gerade die Codebasis. Der nachfolgende 
Programmierer, der hoffentlich mehr Erfahrung hat, kann den Müll dann 
nur noch wegwerfen.

von Alex W. (Gast)


Lesenswert?

Sven schrieb:
> Ich habe einen Programmcode für einen Tiny 84, den ich persönlich
> unleserlich finde.

Dann poste ihn doch mal hier!

von Falk B. (falk)


Lesenswert?

@ Sven (Gast)

>Wenn ich doch eine Methode aufrufe werden doch Daten auf den Stack

Du hast gar keine Methoden sonder schnöde Funktionen, denn das ist 
garantiert "nur" C und kein C++.

>geschrieben und eine Sprunganweisung ausgeführt. Wenn ich dagegen den
>Code Sequentiell ausführe, dann benutzt er keine Sprunganweisung und
>muss auch nicht notwendigerweise Daten auf dme Stack schrieben und
>sichern.

Richtig. Solche Sachen darf man natürlich nicht in zeitkritische 
Sequenzen einbauen.

von Einer K. (Gast)


Lesenswert?

Sven schrieb:
> main()
> {
>  int a,b, c;
>  a =2;
>  b=3;
>  c = a + b;
> }
1
int main()
2
{
3
 int a = 2;
4
 int b = 3;
5
 int c = a + b;
6
}
Mehr kann man da aus meiner Sicht kaum raus holen!

Vielleicht noch so:
1
int main()
2
{
3
 const int a = 2;
4
 const int b = 3;
5
 int c = a + b;
6
}

Sven schrieb:
> Wenn ich doch eine Methode aufrufe werden doch Daten auf den Stack
> geschrieben und eine Sprunganweisung ausgeführt. Wenn ich dagegen den
> Code Sequentiell ausführe, dann benutzt er keine Sprunganweisung und
> muss auch nicht notwendigerweise Daten auf dme Stack schrieben und
> sichern.

Du meinst "Funktion"..
Gegen den Overhead wurde das Attribut "inline" (Empfehlung an den 
Compiler),  oder das noch bestimmtere, Compiler spezifische Attribut, 
"__attribute__((always_inline))" erfunden.

von Christopher J. (christopher_j23)


Lesenswert?

Mit den Optimierungsstufen -Os bzw. -O2 sollte der Compiler sowieso 
alles inlinen, sofern es entweder den Code schrumpft oder schneller 
macht, oder eben beides.

von Peter (Gast)


Lesenswert?

Sven schrieb:
> main()
> {
> #SUMME
> }

Um Himmels Willen! Bitte nicht! Das ist ja nochmal eine Stufe schlimmer 
als Macros. Für so etwas gibt es Unterprogramme aka Funktionen.
1
static int summe(const int a, const int b)
2
{
3
    return (a + b);
4
}
(Überprüfung auf Überlauf usw. jetzt mal außen vor gelassen)

von Peter D. (peda)


Lesenswert?

Welche Programmiersprache soll das überhaupt sein?
Der AVR-GCC meint dazu:
1
error: invalid preprocessing directive #SUMME

von Einer K. (Gast)


Lesenswert?

Peter D. schrieb:
> Welche Programmiersprache soll das überhaupt sein?
> Der AVR-GCC meint dazu:
Da das sowieso ein Irrweg ist .....
Ist auch das egal.

von A. (Gast)


Lesenswert?

Brauchst du auf einem Tiny wirklich int für so kleine Zahlen?
Es lässt sich bestimmmt einiges optimieren. Dazu musst du aber mal den 
Code zeigen.

von NichtWichtig (Gast)


Lesenswert?

so define Künstler hatte ich früher auch mal als Kollege.
Auf den ersten Blick alles schön kompakt... aber dann ... pures 
Entsetzen :O


Unsere coding guide lines verbieten defines und fordern auf const zu 
verwenden.

von Einer K. (Gast)


Lesenswert?

NichtWichtig schrieb:
> Unsere coding guide lines verbieten defines und fordern auf const zu
> verwenden.

Leitsatz:
Jedes vermiedene Define ist ein gutes Define.
Jedes vermeidbare Define ist ein böses Define.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

NichtWichtig schrieb:
> Unsere coding guide lines verbieten defines und fordern auf const zu
> verwenden.

Hmmm... warum muss die (Coding-) Welt immer schwarz und weiss sein?

Vermutlich verbietet ihr auch GOTO ;-)

von achs (Gast)


Lesenswert?

Du solltest ein echtes Beispiel posten. Wenn das der Original-Code war:

Sven schrieb:
1
void main(void)
2
{
3
int a,b,c;
4
5
   a = 2;
6
   b = 3;
7
   c = a + b;
8
}

dann macht sinnloses Zerreißen in Funktionen es nicht besser.

(OK, ist natürlich kein Originalcode, da sinnfrei. Aber was Du daraus 
gemacht hast, ist grausam)

Darum wirklich mal eine originale Funktion posten.

von lol (Gast)


Lesenswert?

Code zu strukturieren bedeutet
- logisch zusammenhängende Codestücke zusammenfassen
- wieder verwendbare Elemente in Funktionen kapseln
- Code zu dokumentieren
- eine Gruppe von wieder verwendbaren Codeblöcken in eigene Libs(.h/.c) 
zusammen fassen
- Problemstellungen in logisch zusammenhängende Unteraufgaben zerteilen 
und dann in überschaubaren Funktionsblöcken implementieren.

Code zu strukturieren bedeutet nicht, Code zu schreiben und dann einen 
Platzhalter generieren, damit es an irgendeiner Stelle kürzer aussieht.

c = a + b; ist weder komplex genug als das es wieder verwendet werden 
könnte, noch ergibt sich eine Notwendigkeit, es überschaubarer zu 
machen.

von Einer K. (Gast)


Lesenswert?

Ich kenne das so:
Die Regeln sind schwarz weiß.
Ausnahmen müssen begründet und abgesegnet werden.

von Markus F. (mfro)


Lesenswert?

"Modularisieren" im eigentlichen Sinn (Code in einzelne, funktional 
getrennte Module aufteilen) kann durchaus dazu führen, dass Programme 
grösser und/oder langsamer werden.

Gcc kann nur dann wirklich vernünftige Entscheidungen zum Inlining 
treffen, wenn es den gesamten relevanten Code "auf einmal" zu sehen 
bekommt. Wenn der aufgerufene Code plötzlich in einem anderen Modul 
steckt, ist das u.U. nicht mehr der Fall und es kommt ein 
Funktionsaufruf mit Prolog/Epilog dazu, wo vorher keiner war. Effekt: 
das Programm wird u.U. langsamer und grösser.

LTO sollte das eigentlich vermeiden. Benutzt Du das?

von Löser (Gast)


Lesenswert?

Michael R. schrieb:
> Vermutlich verbietet ihr auch GOTO ;-)

Kannst du eine sinnvolle Verwendung für Goto nennen, die nicht durch 
sicherere und lesbarere Konstrukte ersetzt werden kann?

von Einer K. (Gast)


Lesenswert?

Löser schrieb:
> sicherere

Was ist an Goto unsicher?

Und ja, man kann mit jedem Sprachmittel Mist bauen!

von Daniel H. (Firma: keine) (commander)


Lesenswert?

Löser schrieb:
> Kannst du eine sinnvolle Verwendung für Goto nennen, die nicht durch
> sicherere und lesbarere Konstrukte ersetzt werden kann?

Beispielsweise um aus verschachtelten Schleifen rauszuspringen.
1
while(...)
2
{
3
    while(...)
4
    {
5
        if(exitCondition)
6
        {
7
            goto exit;
8
        }
9
    }
10
}
11
12
exit:
13
...

von Löser (Gast)


Lesenswert?

Daniel H. schrieb:
> Löser schrieb:
> Kannst du eine sinnvolle Verwendung für Goto nennen, die nicht durch
> sicherere und lesbarere Konstrukte ersetzt werden kann?
>
> Beispielsweise um aus verschachtelten Schleifen
> rauszuspringen.
1
bool_t exit = false;
2
while(...)
3
 {
4
     while(...)
5
     {
6
         if(exitCondition)
7
         {
8
             exit = true;
9
             break;
10
         }
11
     }
12
     if(exit) { break; };
13
 }
14
15
 ...

Meiner Meinung nach sauberer und sicherer. Exit kann auch in jeder 
Funktion gleich heißen für den Erkennungswert, bei Labels muss man sich 
ein Namensschema ausdenken, damit man auch korrekt springt.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Löser schrieb:
> Meiner Meinung nach sauberer und sicherer.

Richtig: DEINER Meinung nach. Meiner Meinung nach nicht :-)

Goto ist nicht böse, nur weil ihr das alle in der Schule gelernt habt.

von Curby23523 N. (Gast)


Lesenswert?

Löser schrieb:
> bool_t exit = false;
> while(...)
>  {
>      while(...)
>      {
>          if(exitCondition)
>          {
>              exit = true;
>              break;
>          }
>      }
>      if(exit) { break; };
>  }
>
>  ...
>
> Meiner Meinung nach sauberer und sicherer. Exit kann auch in jeder
> Funktion gleich heißen für den Erkennungswert, bei Labels muss man sich
> ein Namensschema ausdenken, damit man auch korrekt springt.

Eine Katastrophe. Diese Dogmen gehen mir gewaltig auf die Nerven. Auch 
ein goto kann - wie gezeigt - sinnvoll verwendet werden. Das hier ist 
einfach unleserlich - wobei man eher diese verschachtelten Schleifen 
meiden sollte.

Alle kriegen eingetrichtert, dass goto böse sei, nur weil Anfänger es 
nicht wissen sinvoll einzusetzen und Spaghetticode produzieren. Und alle 
plappern es nach. Kein gutes Zeichen für einen selbstsständig denkenden 
Ingenieur.

Arduino F. schrieb:
> Ich kenne das so:
> Die Regeln sind schwarz weiß.
> Ausnahmen müssen begründet und abgesegnet werden.

Du gehst also zum Chef/Vorgesetzten und fragst "Darf ich hier 
ausnahmsweise mal ein define verwenden?"? Also da/so möchte ich nicht 
arbeiten. Kriegst du auch eine Abmahnung, solltest du dochmal 
unerlaubterweise ein goto/define verwenden? Wird dein Code Zeile für 
Zeile überprüft, ob du nur erlaubte C-ELemente verwendet hast? Und das 
bei Arduino, wo doch eh egal ist was man eintippt..

von Einer K. (Gast)


Lesenswert?

Nils N. schrieb:
> Du gehst also zum Chef/Vorgesetzten und fragst "Darf ich hier
> ausnahmsweise mal ein define verwenden?"? Also da/so möchte ich nicht
> arbeiten. Kriegst du auch eine Abmahnung, solltest du dochmal
> unerlaubterweise ein goto/define verwenden? Wird dein Code Zeile für
> Zeile überprüft, ob du nur erlaubte C-ELemente verwendet hast? Und das
> bei Arduino, wo doch eh egal ist was man eintippt..

Du bist doch nicht ganz dicht!

Auch wenn dir das fremd sein mag...
Es gibt einen deutlichen Unterschied zwischen Richtlinien und Dogmen.

Ich glaube nicht, dass ein Team ohne Richtlinien erfolgreich arbeiten 
kann.

von Rolf M. (rmagnus)


Lesenswert?

Michael R. schrieb:
> NichtWichtig schrieb:
>> Unsere coding guide lines verbieten defines und fordern auf const zu
>> verwenden.
>
> Hmmm... warum muss die (Coding-) Welt immer schwarz und weiss sein?

Genau meine Rede. Schwarz/weiß ist für Anfänger gut, damit sie nicht 
gleich in jedes Fettnäpfchen treten, weil sie ein Feature falsch 
benutzen. Aber es gibt sehr wenige Features der Sprache, die wirklich 
niemals sinnvoll sind.

Löser schrieb:
> Meiner Meinung nach sauberer und sicherer.

Warum? Ich finde es unübersichtlicher durch die zusätzlich nötige 
Hilfsvariable. Solche Hilfsvariablen sind für mich Krücken, die ich 
gerne vermeide. Und was soll daran sicherer sein?
Für mich klingt die Aussage, als ob dir mal eingetrichtert wurde, dass 
goto der Hölle entstamme und unter allen Umständen zwingend zu vermeiden 
sei, weil sonst die Apokalypse droht oder sowas.

> Exit kann auch in jeder Funktion gleich heißen für den Erkennungswert,
> bei Labels muss man sich ein Namensschema ausdenken, damit man auch
> korrekt springt.

Nein, warum sollte man das müssen? Das kann auch in jeder Funktion 
gleich heißen.

von Curby23523 N. (Gast)


Lesenswert?

Arduino F. schrieb:
> Du bist doch nicht ganz dicht!

Das waren deine Worte: Ausnahmen müssen begründet und abgesegnet werden.
Und wir redeten hier über defines. Also wenn du ein define verwenden 
willst, muss das abgesegnet werden.

In meiner letzten Firma gab es auch den Versuch, solche 
Anweisungen/Richtlinien bzgl. Formatierung durchzusetzen. Letztenendes 
war das aber eher hinderlich als nützlich und ist somit wieder in der 
Schublade verschwunden.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Rolf M. schrieb:
> weil sonst die Apokalypse droht

Mindestens! Aber die Große!

Und um der kleinen Apokalypse (das ist die ohne Pferde) zu entgehen, 
verbietet man am besten auch "early return"! Sicher ist sicher...

irgendwas läuft da in der Ausbildung der "Coder" falsch...

von Einer K. (Gast)


Lesenswert?

Nils N. schrieb:
> Also wenn du ein define verwenden
> willst, muss das abgesegnet werden.

Die Frage ist, willst du es wirklich wissen, oder nur Streit...
Wenn Streit, dann sollten wir das hier schnell beenden.


Eine der Leitlinien habe ich hier schon genannt:

Arduino F. schrieb:
> Leitsatz:
> Jedes vermiedene Define ist ein gutes Define.
> Jedes vermeidbare Define ist ein böses Define.

Die beiden Sätze haben sowas wie eine Hysterese...
Den Bereich der unvermeidbaren Defines.
Und den Bereich wo das krampfhafte vermeiden von Defines zu Nachteilen 
irgendwelcher Art führt.

Was der TE mit Defines anstellt wäre bei uns ein NoGo.

Was für Defines gilt, gilt auch für Gotos.
Z.B. Beitrag "Re: Lesbarer ProgrammCode"
Was da mit dem Exitflag gemacht wird, heißt bei uns "Eiertanz".

Und ja, mein Code wird von anderen geprüft. Das wird nicht eingefordert, 
sondern passiert automatisch. Es müssen ja auch meist andere daran/damit 
weiterarbeiten.

Im Grunde muss man jederzeit, jedem im Team, erklären können was, und 
warum man es so getan hat, oder tun will. Die anderen melden sich dann 
schon, wenn es bessere/elegantere Wege gibt.

Im Grunde bringt einen das krampfhafte festhalten an Dogmen nicht 
weiter.
Die Leitsätze und Regeln sind eine Vereinbarung, welche einem das Leben 
erleichtern. Die Teamarbeit erleichtern.
Ein bisschen so, wie der Unterschied zwischen einem gepflasterten Weg, 
und der Kugel am Bein.

Vergleiche es mit der durchgezogenen Mittellinie auf einer Straße. Es 
ist für alle Verkehrsteilnehmer angenehm, wenn sich jeder daran hält. 
Die Linie ist ja meist auch mit Grund da.

Aber dennoch, darf/muss ich sie in manchen Situationen überfahren. Diese 
Einsicht darf allerdings nicht dazu führen, dass ab dem ersten 
Überfahren, alle weißen Linien dieser Welt ignoriert werden.

Nils N. schrieb:
> In meiner letzten Firma gab es auch den Versuch, solche
> Anweisungen/Richtlinien bzgl. Formatierung durchzusetzen. Letztenendes
> war das aber eher hinderlich als nützlich und ist somit wieder in der
> Schublade verschwunden.
Ja, das hört sich so an, als wäre das bei euch schief gelaufen.
Vielleicht zu übertrieben, zu krampfhaft..
Eine Weisung "von oben"?

von Oliver J. (skriptkiddy)


Lesenswert?

Löser schrieb:
> Michael R. schrieb:
>> Vermutlich verbietet ihr auch GOTO ;-)
>
> Kannst du eine sinnvolle Verwendung für Goto nennen, die nicht durch
> sicherere und lesbarere Konstrukte ersetzt werden kann?

Effizientere Fehlerbehandlung in Linux-Kernel-Treibern [1]. Wobei ich es 
selbst auch nicht verwende. Man kommt ohne aus. Es scheint aber 
Anwendungsfälle zu geben, bei den es durchaus sinnvoll ist.


[1] 
https://books.google.de/books?id=KjVODAAAQBAJ&pg=PT72&lpg=PT72&dq=linux+treiber+goto&source=bl&ots=h22OK064P_&sig=Ioko7_uEKaEaw2EzbvM3T9MB5Ts&hl=de&sa=X&ved=0ahUKEwjPsu7bqubYAhWHKewKHSbgBeEQ6AEIKzAA#v=onepage&q=linux%20treiber%20goto&f=false

Grüße Oliver

von Oliver S. (oliverso)


Lesenswert?

Löser schrieb:
> Meiner Meinung nach sauberer und sicherer.

Und weil das so super sauber und sicher ist, hat man in C++ exceptions 
erfunden.

Oliver

von Oliver J. (skriptkiddy)


Lesenswert?

Oliver S. schrieb:
> Löser schrieb:
>> Meiner Meinung nach sauberer und sicherer.
>
> Und weil das so super sauber und sicher ist, hat man in C++ exceptions
> erfunden.
>
> Oliver

Exceptionhandling kostet aber schon einiges mehr an Rechenzeit und ist 
in C nicht verfügbar. Das sollte man hier fairerweise auch mit 
betrachten.

Grüße Oliver

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Oliver S. schrieb:
> Und weil das so super sauber und sicher ist, hat man in C++ exceptions
> erfunden.

Exceptions haben leider so gar nichts mit mehr oder weniger sinnvollen 
Anwendung von Goto zu tun.

Und ich behaupte, man kann mit Exceptions (oder dem Werfen ebensolcher) 
Code viel zuverlässiger unlesbar machen als mit Goto.

von Rolf M. (rmagnus)


Lesenswert?

Arduino F. schrieb:
> Nils N. schrieb:
>> Also wenn du ein define verwenden
>> willst, muss das abgesegnet werden.
>
> Die Frage ist, willst du es wirklich wissen, oder nur Streit...
> Wenn Streit, dann sollten wir das hier schnell beenden.

Wieso? Das hast du doch selbst geschrieben:

Arduino F. schrieb:
> Ausnahmen müssen begründet und abgesegnet werden.

Also heißt das, du musst zu dem gehen, der die Autorität darüber hat und 
bei dem beantragen, dass du ein define machen darfst. Oder was sonst 
verstehst du unter "abgesegnet werden"?

> Eine der Leitlinien habe ich hier schon genannt:
>
> Arduino F. schrieb:
>> Leitsatz:
>> Jedes vermiedene Define ist ein gutes Define.
>> Jedes vermeidbare Define ist ein böses Define.
>
> Die beiden Sätze haben sowas wie eine Hysterese...
> Den Bereich der unvermeidbaren Defines.
> Und den Bereich wo das krampfhafte vermeiden von Defines zu Nachteilen
> irgendwelcher Art führt.

Das ist ja ok, erklärt aber noch nicht, wie das "abgesegnet werden" 
funktioniert.

> Im Grunde bringt einen das krampfhafte festhalten an Dogmen nicht
> weiter.
> Die Leitsätze und Regeln sind eine Vereinbarung, welche einem das Leben
> erleichtern. Die Teamarbeit erleichtern.
> Ein bisschen so, wie der Unterschied zwischen einem gepflasterten Weg,
> und der Kugel am Bein.

Ja. Von jeder Regel gibt es Ausnahmen, da sich nicht alles zu 100% 
sinnvoll in ein starres Regelwerk pressen lässt. Kann man machen, aber 
wenn man Dinge komplizierter macht, nur weil die Regel die Vereinfachung 
verbietet, ist was falsch gelaufen.

> Vergleiche es mit der durchgezogenen Mittellinie auf einer Straße. Es
> ist für alle Verkehrsteilnehmer angenehm, wenn sich jeder daran hält.
> Die Linie ist ja meist auch mit Grund da.
>
> Aber dennoch, darf/muss ich sie in manchen Situationen überfahren. Diese
> Einsicht darf allerdings nicht dazu führen, dass ab dem ersten
> Überfahren, alle weißen Linien dieser Welt ignoriert werden.

Allerdings muss das Überfahren der Linie nicht vorher abgesegnet werden, 
denn das wäre etwas unpraktisch. ;-)

von Daniel A. (daniel-a)


Lesenswert?

Oliver J. schrieb:
> Exceptionhandling kostet aber schon einiges mehr an Rechenzeit und ist
> in C nicht verfügbar.

Kann man mit setjmp nachbilden. exceptions4c macht das sehr elegant: 
https://github.com/guillermocalvo/exceptions4c

Man kann in C eben schon wirklich alles machen. Wenn man es wirklich 
beherrscht, fragt man sich nichtmehr wie etwas möglich ist, sondern 
nurnoch wie man es am liebsten aufschreiben will. Wenn man ersteinmal 
soweit ist, ist Programmieren wie das Mahlen eines Kunstwerks, man steht 
über dem Syntax und den Einschränkungen, über den Regeln der 
Programmiersprache, und kann alles tun, was die Vorstellungskraft 
erlaubt. (wobei man das trotzdem nicht immer tun sollte)

von Rolf M. (rmagnus)


Lesenswert?

Daniel A. schrieb:
> Oliver J. schrieb:
>> Exceptionhandling kostet aber schon einiges mehr an Rechenzeit und ist
>> in C nicht verfügbar.
>
> Kann man mit setjmp nachbilden. exceptions4c macht das sehr elegant:
> https://github.com/guillermocalvo/exceptions4c
>
> Man kann in C eben schon wirklich alles machen. Wenn man es wirklich
> beherrscht, fragt man sich nichtmehr wie etwas möglich ist, sondern
> nurnoch wie man es am liebsten aufschreiben will.

Oder man fragt sich, ob man nicht lieber eine Sprache nimmt, bei der man 
das nicht zu Fuß machen muss. Nicht falsch verstehen: Ich mache viel in 
C, aber die ganzen Sprachmittel von C++ will ich damit nicht nachbilden 
müssen. Da gehören vor allem gerade so Sachen wie Exceptions oder 
Polymorphie dazu.
Und spätestens bei Templates kann man auch nicht mehr alles in C machen, 
ohne sich noch einen eigenen Codegenerator zu schreiben.

> Wenn man ersteinmal soweit ist, ist Programmieren wie das Mahlen eines
> Kunstwerks,

Das trifft's ein bisschen, wenn auch nicht auf die von dir gewünschte 
Art (du hast vermutlich "Malen" und nicht "Mahlen" gemeint). ;-)

: Bearbeitet durch User
von Einer K. (Gast)


Lesenswert?

Rolf M. schrieb:
> Wieso? Das hast du doch selbst geschrieben:

Rolf M. schrieb:
> Also heißt das, du musst zu dem gehen, der die Autorität darüber hat und
> bei dem beantragen, dass du ein define machen darfst. Oder was sonst
> verstehst du unter "abgesegnet werden"?

Deine Art zu zitieren/lesen ist recht seltsam...
Das einzige, was deine Frage wirklich beantwortet, wird ignoriert.

Es macht auch keinen Sinn auf "vorher Absegnen" zu beharren.
Denn ganz offensichtlich habe ich was anderes gemeint, als du darunter 
verstehen möchtest. Und "vorher" habe ich schon gar nicht gesagt.
Bitte streiche das Wort "Absegnen" in meinen Texten, bis wir uns über 
die Semantik geeinigt haben.

Hier nochmal, denn deutlicher kann ich es nicht:

Arduino F. schrieb:
> Und ja, mein Code wird von anderen geprüft. Das wird nicht eingefordert,
> sondern passiert automatisch. Es müssen ja auch meist andere daran/damit
> weiterarbeiten.
>
> Im Grunde muss man jederzeit, jedem im Team, erklären können was, und
> warum man es so getan hat, oder tun will. Die anderen melden sich dann
> schon, wenn es bessere/elegantere Wege gibt.

Hat also wenig mit Hierarchie, oder so, zu tun...
Eher anders rum, denn gerade Neueinsteiger hinterfragen den Code.
Die Erfahrenen wissen, dass es zu fast jedem Problem mehrere Lösungen 
gibt. Und sie sehen auch, recht schnell, ob die gewählte Lösung 
tragfähig ist.

von Rolf M. (rmagnus)


Lesenswert?

Arduino F. schrieb:
> Rolf M. schrieb:
>> Also heißt das, du musst zu dem gehen, der die Autorität darüber hat und
>> bei dem beantragen, dass du ein define machen darfst. Oder was sonst
>> verstehst du unter "abgesegnet werden"?
>
> Deine Art zu zitieren/lesen ist recht seltsam...
> Das einzige, was deine Frage wirklich beantwortet, wird ignoriert.

Mir war nicht klar, dass das die Antwort sein sollte, da ich unter 
"absegnen" was anderes verstanden hatte.

Arduino F. schrieb:
> Es macht auch keinen Sinn auf "vorher Absegnen" zu beharren.
> Denn ganz offensichtlich habe ich was anderes gemeint, als du darunter
> verstehen möchtest.

Ja, ganz offensichtlich. Deshalb hab ich ja auch explizit gefragt, was 
du damit gemeint hast:

Rolf M. schrieb:
> Oder was sonst verstehst du unter "abgesegnet werden"?


> Und "vorher" habe ich schon gar nicht gesagt.

Gehört für mich irgendwie dazu. Ich frage um Erlaubnis, etwas zu tun, 
bevor ich es tue und nicht erst, nachdem ich es schon getan habe. Und 
ich (und andere wohl auch) dachte, genau das hättest du mit "abgesegnet 
werden" gemeint: Dass du vorher um Erlaubnis fragst.

von Possetitjel (Gast)


Lesenswert?

Michael R. schrieb:

> NichtWichtig schrieb:
>> Unsere coding guide lines verbieten defines und fordern
>> auf const zu verwenden.
>
> Hmmm... warum muss die (Coding-) Welt immer schwarz und
> weiss sein?

Weil die formale Logik auch nur schwarz und weiss ist:
Entweder das Sprachkonstrukt liefert definierten Compiler-
output, oder es tut es nicht.


> Vermutlich verbietet ihr auch GOTO ;-)

Ich kenne kein überzeugendes Argument, es nicht zu tun. Hier
im Thread kam jedenfalls noch keins :)

(Und dass man in der Schule gelernt hat, Goto sei böse,
heisst ja nicht automatisch, dass es in Wahrheit gut ist,
nicht wahr?! Nicht ALLES, was man in der Schule lernt, ist
falsch.)

von Rolf M. (rmagnus)


Lesenswert?

Possetitjel schrieb:
>> Hmmm... warum muss die (Coding-) Welt immer schwarz und
>> weiss sein?
>
> Weil die formale Logik auch nur schwarz und weiss ist:
> Entweder das Sprachkonstrukt liefert definierten Compiler-
> output, oder es tut es nicht.

Es ging hier aber nicht darum, ob etwas formalsprachlich korrekt ist 
oder nicht, sondern darum, ob es sinnvoll ist, korrekte Konstrukte 
pauschal zu verbieten, weil sie von Anfängern gerne falsch benutzt 
werden.

>> Vermutlich verbietet ihr auch GOTO ;-)
>
> Ich kenne kein überzeugendes Argument, es nicht zu tun. Hier
> im Thread kam jedenfalls noch keins :)

Doch, beide Situationen, in denen es sinnvoll sein kann, wurden genannt.

> (Und dass man in der Schule gelernt hat, Goto sei böse,
> heisst ja nicht automatisch, dass es in Wahrheit gut ist,
> nicht wahr?! Nicht ALLES, was man in der Schule lernt, ist
> falsch.)

Das hat auch keiner behauptet. Aber umgekehrt sollte man auch nicht 
alles, was man in der Schule gelernt hat, unreflektiert übernehmen und 
zum Dogma machen. Man darf Regeln auch hinterfragen.
Nils hat es gut auf den Punkt gebracht:

Nils N. schrieb:
> Alle kriegen eingetrichtert, dass goto böse sei, nur weil Anfänger es
> nicht wissen sinvoll einzusetzen und Spaghetticode produzieren. Und alle
> plappern es nach. Kein gutes Zeichen für einen selbstsständig denkenden
> Ingenieur.

von Possetitjel (Gast)


Lesenswert?

Rolf M. schrieb:

> Es ging hier aber nicht darum, ob etwas formalsprachlich
> korrekt ist oder nicht, sondern darum, ob es sinnvoll ist,
> korrekte Konstrukte pauschal zu verbieten, weil sie von
> Anfängern gerne falsch benutzt werden.

Wenn man ernsthaft darüber diskutieren kann, die Verwendung
eines formalsprachlich korrekten Konstruktes zu verbieten,
dann ist die Sprachdefinition schlecht.

Und genau das ist auch meine (Außenseiter-)Meinung.

Da man aber i.d.R. nicht die Macht hat, das Übel an der
Wurzel zu packen, beschränkt man sich auf die Symptom-
behandlung und verbietet eben die Verwendung von goto.

Gäbe es das Sprachelement gar nicht, gäbe es auch die
Diskussion nicht, und niemand würde sich aufregen.

>>> Vermutlich verbietet ihr auch GOTO ;-)
>>
>> Ich kenne kein überzeugendes Argument, es nicht zu tun.
>> Hier im Thread kam jedenfalls noch keins :)
>
> Doch, beide Situationen, in denen es sinnvoll sein kann,
> wurden genannt.

Es ging mir nicht darum, dass das Sprachelement in manchen
Fällen hübsch und nett sein kann (das gestehe ich ja zu) --
es ging darum, dass der Schaden meiner Meinung nach den
Nutzen weit überwiegt und dass es deshalb sehr wohl sinnvoll
ist, die Verwendung zu verbieten.

Um das nochmal klar zu sagen: Die Tatsache, dass es den
Experten in manchen Fällen eine etwas elegantere
Formulierung erlaubt, ist keine hinreichende Begründung,
ein Sprachelement in den Standard aufzunehmen. Dazu wäre
schon etwas mehr notwendig.

>> (Und dass man in der Schule gelernt hat, Goto sei böse,
>> heisst ja nicht automatisch, dass es in Wahrheit gut ist,
>> nicht wahr?! Nicht ALLES, was man in der Schule lernt, ist
>> falsch.)
>
> Das hat auch keiner behauptet. Aber umgekehrt sollte man
> auch nicht alles, was man in der Schule gelernt hat,
> unreflektiert übernehmen und zum Dogma machen.

Dass das eine handfeste Beleidigung ist, ist Dir bewusst?

Dass das meine Neigung, über die Gründe meiner Meinung
zu diskutieren, ggf. negativ beeinflussen könnte, ist
beabsichtigt?

> Man darf Regeln auch hinterfragen.

Ja.

Und ich darf dabei auch zu anderen Ergebnissen kommen als Du,
und ich darf diese abweichende Meinung sogar öffentlich
vertreten.

von Peter D. (peda)


Lesenswert?

Nun, den Sven scheinen wir ja gründlich verschreckt zu haben. Neugierig 
wäre ich allerdings schon, was er wirklich meint, zu verbessern. Sein 
bisheriges Beispiel brachte leider keinerlei Klarheit darüber.

von Markus F. (mfro)


Lesenswert?

Possetitjel schrieb:
> dass der Schaden meiner Meinung nach den
> Nutzen weit überwiegt und dass es deshalb sehr wohl sinnvoll
> ist, die Verwendung zu verbieten.

Ja, C ist ein scharfes Messer und scharfe Messer sollten verboten 
werden. Schliesslich könnte man sich dran verletzen.

Auf die paar Chirurgen, die mit scharfen Messern umgehen können, kommt's 
nicht an, die können doch - wie jeder andere auch - stattdessen 
Plastiklöffel nehmen.

von Einer K. (Gast)


Lesenswert?

Possetitjel schrieb:
> (Und dass man in der Schule gelernt hat, Goto sei böse,
> heisst ja nicht automatisch, dass es in Wahrheit gut ist,
> nicht wahr?! Nicht ALLES, was man in der Schule lernt, ist
> falsch.)

Manche Annahmen/Behauptungen/Regeln sind so dermaßen falsch, dass noch 
nicht einmal das Gegenteil richtig ist.

von Possetitjel (Gast)


Lesenswert?

Markus F. schrieb:

> Possetitjel schrieb:
>> dass der Schaden meiner Meinung nach den Nutzen weit
>> überwiegt und dass es deshalb sehr wohl sinnvoll ist,
>> die Verwendung zu verbieten.
>
> Ja, C ist ein scharfes Messer

Nein.
C ist eine alte Drehbank, ohne Futterschutz, ohne
Drehmomentsicherung, ohne Not-Aus und mit
Transmissionsantrieb.

> und scharfe Messer sollten verboten werden.

Nein, s.o.

> Auf die paar Chirurgen, die mit scharfen Messern umgehen
> können, kommt's nicht an, [...]

Du musst weder meiner Meinung sein noch meinen Standpunkt
nachvollziehen können -- aber es wäre schön, wenn Du meine
Argumente wenigstens zur Kenntnis nehmen und verstehen
würdest.

Wenn es Fälle gäbe, in denen goto NOTWENDIG, d.h.
UNVERZICHTBAR ist, dann könnte man ja darüber reden.

Wenn es aber nur in wenigen Fällen zu ELEGANTEREN Programmen
führt, stimmt das Aufwand-Nutzen-Verhältnis nicht.

von Einer K. (Gast)


Lesenswert?

Possetitjel schrieb:
> Wenn es Fälle gäbe, in denen goto NOTWENDIG, d.h.
> UNVERZICHTBAR ist, dann könnte man ja darüber reden.

Wenn es einen Grund geben würde, es zu verbieten, dann würde man es aus 
dem Standard werfen.

von Rolf M. (rmagnus)


Lesenswert?

Possetitjel schrieb:
> Rolf M. schrieb:
>
>> Es ging hier aber nicht darum, ob etwas formalsprachlich
>> korrekt ist oder nicht, sondern darum, ob es sinnvoll ist,
>> korrekte Konstrukte pauschal zu verbieten, weil sie von
>> Anfängern gerne falsch benutzt werden.
>
> Wenn man ernsthaft darüber diskutieren kann, die Verwendung
> eines formalsprachlich korrekten Konstruktes zu verbieten,
> dann ist die Sprachdefinition schlecht.

Ich bin ja nicht der, der die Nutzung solcher Konstrukte verbieten will.

> Gäbe es das Sprachelement gar nicht, gäbe es auch die
> Diskussion nicht, und niemand würde sich aufregen.

Naja, höchstens darüber, dass es für bestimmte Dinge nur unnötig 
umständliche Lösungen gibt. Ist ja bei anderen Sachen, die es in C nicht 
gibt, auch so.

> Es ging mir nicht darum, dass das Sprachelement in manchen
> Fällen hübsch und nett sein kann (das gestehe ich ja zu) --
> es ging darum, dass der Schaden meiner Meinung nach den
> Nutzen weit überwiegt und dass es deshalb sehr wohl sinnvoll
> ist, die Verwendung zu verbieten.

Das sehe ich eben anders. Ich finde es recht unsinnig, ein existierendes 
Sprachfeature an einer Stelle, wo es die sinnvollste Lösung wäre, nur 
deshalb nicht einzusetzen, weil man es für böse erklärt hat.

> Um das nochmal klar zu sagen: Die Tatsache, dass es den
> Experten in manchen Fällen eine etwas elegantere
> Formulierung erlaubt, ist keine hinreichende Begründung,
> ein Sprachelement in den Standard aufzunehmen. Dazu wäre
> schon etwas mehr notwendig.

Programmierung ist ein kompliziertes Handwerk. Da sind manchmal auch 
Werkzeuge sinnvoll, mit denen nur Experten richtig umgehen können. Für 
eine CNC-Fräse muss man auch erstmal lernen, wie man sie benutzt. Das 
heißt aber nicht, dass man deshalb alle - auch die, die den Umgang 
damit gelernt haben - zwingen sollte, stattdessen alles mit der Feile zu 
bearabeiten. Den Azubi, der gestern angefangen hat, lässt man aber 
besser nicht an die Maschine. Klar, ist ein etwas überzogener Vergleich, 
aber macht deutlich, was ich meine: Nur weil es auch Leute gibt, die ein 
bestimmtes Werkzeug nicht benutzen können, sollte man deshalb nicht 
gleich auch alle anderen dazu zwingen es nicht zu benutzen.

>> Das hat auch keiner behauptet. Aber umgekehrt sollte man
>> auch nicht alles, was man in der Schule gelernt hat,
>> unreflektiert übernehmen und zum Dogma machen.
>
> Dass das eine handfeste Beleidigung ist, ist Dir bewusst?

Wo du da eine Beleidigung zu sehen glaubst, vermag ich nicht zu 
erkennen. Es war jedenfalls nicht meine Absicht, irgendwen zu 
beleidigen.

>> Man darf Regeln auch hinterfragen.
>
> Ja.
>
> Und ich darf dabei auch zu anderen Ergebnissen kommen als Du,
> und ich darf diese abweichende Meinung sogar öffentlich
> vertreten.

Natürlich. Nur habe ich bei den meisten von denen, die goto vehement 
ablehnen, nicht den Eindruck, dass das aufgrund selbst gebildeter 
Meinung passiert.

Possetitjel schrieb:
> Wenn es Fälle gäbe, in denen goto NOTWENDIG, d.h.
> UNVERZICHTBAR ist, dann könnte man ja darüber reden.

Zwingend notwendig sind nur sehr wenige Sprachfeatures (auch Brainfuck 
ist Touring-vollständig). Deshalb muss man ja nicht gleich alles andere 
abschaffen.

> Wenn es aber nur in wenigen Fällen zu ELEGANTEREN Programmen
> führt, stimmt das Aufwand-Nutzen-Verhältnis nicht.

Welcher Aufwand?

: Bearbeitet durch User
von Markus F. (mfro)


Lesenswert?

Ich gebe gern zu, dass goto eigentlich nicht notwendig ist (bzw. - 
s.u. nicht notwendig sein sollte) und wenn, dann nur sehr sparsam 
eingesetzt werden sollte.

Ich gestehe, ich habe in - ich weiss nicht - mehr als dreissig Jahren 
vielleicht 100x goto verwendet (pfui!). Nicht, weil ich's unbedingt 
gebraucht hätte, sondern weil es in der Situation die einfachere, 
leichter lesbare, einfach bessere Lösung war.

Tatsächlich war sicher deutlich mehr als die Hälfte davon kein eigener 
Code, sondern der Pfusch anderer Leute, die vor lauter Verschachtelung 
am Ende vergessen haben, allokierte Ressourcen frei zu geben. Wenn man 
so was reparieren muss, ohne gleich alles neu zu schreiben (und damit 
die gesamte Testmaschinerie anzuwerfen), ist goto Gold wert. In grossen 
Serveranwendungen werden solche Fehler oft erst im Produktivbetrieb 
gefunden - und dann muss es auch mal schnell und einfach gehen.

Was mich stört ist der sture Dogmatismus, der hier durchscheint.

von Switch (Gast)


Lesenswert?

Sollte man nicht auch switch verbannen, denn das ist doch nur ein 
berechnetes goto. Und Mann kann da Fehler machen, z.B. break vergessen.
Man könnte auch schreiben verbieten, denn manche halten sich nicht an 
die Regeln, die sie in der Schule hätten lernen sollen.
Meine Software wird von Software ùberprüft. Die will aber nicht einer 
Diskussion stellen und meckert nur Dinge, an die sie auch versteht. Und 
da sie die Sprache, die sie prüfen soll, nicht beherrscht, wird eben 
weniger straight forward programmiert. Ein echter Erfolg!

von Löser (Gast)


Lesenswert?

Switch schrieb:
> Sollte man nicht auch switch verbannen, denn das ist doch nur ein
> berechnetes goto.

Aber es ist begrenzt wo du hinspringen kannst, das ist der entscheidende 
Unterschied! Mit Goto kannst du sogar in eine ganz andere Funktion 
springen.

von Daniel A. (daniel-a)


Lesenswert?

Löser schrieb:
> Mit Goto kannst du sogar in eine ganz andere Funktion
> springen.

Wie machst du das denn? Schwarze Magie?

von Possetitjel (Gast)


Lesenswert?

Arduino F. schrieb:

> Possetitjel schrieb:
>> Wenn es Fälle gäbe, in denen goto NOTWENDIG, d.h.
>> UNVERZICHTBAR ist, dann könnte man ja darüber reden.
>
> Wenn es einen Grund geben würde, es zu verbieten, dann
> würde man es aus dem Standard werfen.

Nee, das ist eben der Denkfehler. Es JETZT rauswerfen
zu wollen wäre idiotisch, denn es würde alten Code
kaputtmachen.
Die Hürde, es nachträglich herauszuwerfen, ist viel höher
als die, es von vornherein gar nicht hineinzuschreiben.

von Joachim B. (jar)


Lesenswert?

Arduino F. schrieb:
> Leitsatz:
> Jedes vermiedene Define ist ein gutes Define.
> Jedes vermeidbare Define ist ein böses Define.

was ist an #defines schlecht?

#define WENN if
#define GLEICH ==
#define DOCHANDERS else
WENN( a GLEICH b )
{
printf("a ist gleich b");
}
DOCHANDERS
{
printf("a ist leider nicht gleich b");
}

ich habs zwar noch nie genutzt, aber wer mit Englisch Probleme hat why 
not? :)

von Einer K. (Gast)


Lesenswert?

Wenn du solche Textersetzungen benötigst, dann ist #define genau das 
richtige für dich.
Denn in dem Punkt ist es alternativlos.


Die wichtigsten Nachteile von Präprozessormacros sind:
1. Kryptische Fehlermeldungen in Zeilen, wo das Macro genutzt wird. 
Nicht dort wo es erstellt wurde.
2. Keine Typeprüfung von Parametern usw.
3. Es erschwert das Debuggen, denn der Debugger bekommt die Macros nicht 
zu sehen. Bzw. kann nicht damit umgehen.

Habe ich noch was vergessen?
Bestimmt!
z.B. man baut sich leicht unerwünschte/unerwartete Seiteneffekte ein. 
Und landet dann bei Punkt 3.

von Nico W. (nico_w)


Lesenswert?

Possetitjel schrieb:
> Wenn es Fälle gäbe, in denen goto NOTWENDIG, d.h. UNVERZICHTBAR ist,
> dann könnte man ja darüber reden.
> Wenn es aber nur in wenigen Fällen zu ELEGANTEREN Programmen führt,
> stimmt das Aufwand-Nutzen-Verhältnis nicht.

Das heißt dann, das man auch while und do-while rausschmeißen sollte, 
weil for das alles ja auch abdeckt? ;)

von Nop (Gast)


Lesenswert?

Possetitjel schrieb:

> Wenn man ernsthaft darüber diskutieren kann, die Verwendung
> eines formalsprachlich korrekten Konstruktes zu verbieten,
> dann ist die Sprachdefinition schlecht.

Nein, sondern dann wurde die Sprache eben von Profis entworfen, die auch 
genau wußten, wieso sie goto aufgenommen haben. Wenn ich mir ansehe, wie 
man in Pascal üblicherweise gestackte Fehlerbehandlung ohne goto macht, 
oder auch Ausstieg aus geschachtelten Schleifen, dann ist das noch 
unübersichtlicher. Das läuft dann nämlich auf tief geschachtelte ifs, 
Code-Duplikation und/oder absurde Hilfs-Variablen hinaus.

Zudem haben 95.34% der Leute, die goto wegen Dijkstras legendärem "goto 
considered harmful"-Papers verreißen, den Aufsatz überhaupt nicht 
begriffen, sondern plappern nur nach, was sie irgendwo aufgeschnappt 
haben.

Das goto, worauf sich Dijkstra damals bezogen hat, und was tatsächlich 
zu Spaghetti geführt hat, war nämlich ein gänzlich anderes. Damals 
konnte man noch anhand absoluter Zeilennummern quer durch das ganze 
Programm springen.

Das hat so gut wie nichts mit C-goto zu tun, was man nur innerhalb einer 
Funktion benutzen kann, und dann auch nur mit benannten Labels statt 
Zeilennummern.

Das Äquivalent des damals kritisierten gotos wäre in C nicht goto, 
sondern eher setjmp/longjmp (nur in besser). Das kennen viele Leute 
nichtmal dem Namen nach, und das ist auch gut so. Denn das ist ein noch 
viel schärferes Schwert als goto, was man für Exception-Handling in C 
nutzen kann.

Richtig ist aber auch, daß Rückwärtssprünge mit goto bedenklich sind, 
auch in C. Das kann man meistens mit einer while-Schleife umgehen, die 
einen Zustandsautomaten enthält. Der ist dann auch übersichtlicher. So 
mache ich jedenfalls algorithmische Rückwärtssprünge, sofern ist nicht 
das letzte bißchen an Performance gerade an der Stelle brauche. Schon 
weil ein Zustandsautomat ein Idiom ist, was jeder nachfolgende 
Programmierer kennt und sofort versteht.

Selbst Vorwärtssprünge mit goto sind in den allermeisten Fällen auf 
Fehlerbehandlung begrenzt. Computed goto, also goto anhand eines 
Label-Arrays per Index, ist leider immer noch nicht Teil des C-Standards 
(GCC und Clang können es). Das kann man aber algorithmisch gut 
gebrauchen, wenn es auf Performance ankommt. Sowas betrifft etwa 
Interpreter, Python sei genannt.

von Nop (Gast)


Lesenswert?

Arduino F. schrieb:
> Wenn du solche Textersetzungen benötigst, dann ist #define genau
> das richtige für dich. Denn in dem Punkt ist es alternativlos.

Man kann sogar statische Webseiten mit einem C-Compiler verwalten, indem 
man im Roh-HTML includes und Macros nutzt und das dann durch einen 
C-Compiler jagt, bei dem man aber nur die Stufe des Präprozessors nutzt.

von Switch (Gast)


Lesenswert?

Daniel A. schrieb:
> Löser schrieb:
>> Mit Goto kannst du sogar in eine ganz andere Funktion
>> springen.
>
> Wie machst du das denn? Schwarze Magie?

So wie immer, wenn Ahnungslosigkeit im Spiel ist.
Dann ist die Überraschung groß, wenn man's dann doch mal probiert.

von Rolf M. (rmagnus)


Lesenswert?

Switch schrieb:
> So wie immer, wenn Ahnungslosigkeit im Spiel ist.

Ja. Wie man hier im Thread sieht, scheint ein Großteil der Ablehnung von 
goto auch schlicht durch Unwissen / Fehlinformation ausgelöst zu sein.
Hier mal die Definition aus der C-Norm:

6.2.1 Scopes of Identifiers
[....]
3 A label name is the only kind of identifier that has function scope. 
It can be used (in a goto statement) anywhere in the function in which 
it appears, and is declared implicitly by its syntactic appearance 
(followed by a : and a statement).

Sprich: Ein Label ist nur lokal innerhalb der Funktion sichtbar, in der 
es deklariert ist. Ich kann selbstverständlich den selben Namen in 
anderen Funktionen wiederverwenden, und ich kann damit nicht über 
Funktionsgrenzen hinweg springen.

: Bearbeitet durch User
von mh (Gast)


Lesenswert?

Rolf M. schrieb:
> 6.2.1 Scopes of Identifiers

ich zitiere noch einen weiteren Teil aus dem Standard (draft N1570), 
damit es auch wirklich alle verstehen.
1
6.8.6.1 The goto statement
2
3
Constraints
4
The identifier in a goto statement shall name a label located somewhere in the enclosing
5
function. A goto statement shall not jump from outside the scope of an identifier having
6
a variably modified type to inside the scope of that identifier.
7
8
Semantics
9
A goto statement causes an unconditional jump to the statement prefixed by the named
10
label in the enclosing function.

von Markus F. (mfro)


Lesenswert?

Switch schrieb:
> Sollte man nicht auch switch verbannen, denn das ist doch nur ein
> berechnetes goto. Und Mann kann da Fehler machen, z.B. break vergessen.

man kann mit einem switch noch viel wildere Sachen machen: 
https://de.wikipedia.org/wiki/Duff%E2%80%99s_Device

von Peter D. (peda)


Lesenswert?

Löser schrieb:
> Mit Goto kannst du sogar in eine ganz andere Funktion
> springen.

Nö, das geht nur mit setjmp/longjmp aus der setjmp.h.

von Switch (Gast)


Lesenswert?

Markus F. schrieb:
> Switch schrieb:
>> Sollte man nicht auch switch verbannen, denn das ist doch nur ein
>> berechnetes goto. Und Mann kann da Fehler machen, z.B. break vergessen.
>
> man kann mit einem switch noch viel wildere Sachen machen:
> https://de.wikipedia.org/wiki/Duff%E2%80%99s_Device

Darum sollte man es verbieten.
Genau wie alles, was Einfachgestrickte nicht verstehen. Es ist nämlich 
unfair, daß die mit den Anderen verglichen werden.

/Ironie off

von Possetitjel (Gast)


Lesenswert?

Nico W. schrieb:

> Possetitjel schrieb:
>> Wenn es Fälle gäbe, in denen goto NOTWENDIG, d.h. UNVERZICHTBAR
>> ist, dann könnte man ja darüber reden.
>> Wenn es aber nur in wenigen Fällen zu ELEGANTEREN Programmen
>> führt, stimmt das Aufwand-Nutzen-Verhältnis nicht.
>
> Das heißt dann, das man auch while und do-while rausschmeißen
> sollte, weil for das alles ja auch abdeckt? ;)

Nein. "for" und "Eleganz" ist ein inhärenter Widerspruch. ;)

Man sollte "for" als Ausgeburt eines Sprachsadisten verbieten
und nur "while" und "do-while" erlauben...

Beitrag #5288717 wurde von einem Moderator gelöscht.
von Possetitjel (Gast)


Lesenswert?

Rolf M. schrieb:

> Possetitjel schrieb:
>> Rolf M. schrieb:
>>
>>> Es ging hier aber nicht darum, ob etwas formalsprachlich
>>> korrekt ist oder nicht, sondern darum, ob es sinnvoll ist,
>>> korrekte Konstrukte pauschal zu verbieten, weil sie von
>>> Anfängern gerne falsch benutzt werden.
>>
>> Wenn man ernsthaft darüber diskutieren kann, die Verwendung
>> eines formalsprachlich korrekten Konstruktes zu verbieten,
>> dann ist die Sprachdefinition schlecht.
>
> Ich bin ja nicht der, der die Nutzung solcher Konstrukte
> verbieten will.

Ich auch nicht -- aber wir diskutieren ja (getriggert durch
den Scherz von Michael) darüber, ob das ggf. legitim wäre
oder nicht.

Bei "int" oder "struct" verbietet sich diese Diskussion, weil
klar ist (?!), dass man darauf nicht verzichten will -- aber
bei "goto" ist das ganz offensichtlich nicht so eindeutig.

>> Gäbe es das Sprachelement gar nicht, gäbe es auch die
>> Diskussion nicht, und niemand würde sich aufregen.
>
> Naja, höchstens darüber, dass es für bestimmte Dinge nur
> unnötig umständliche Lösungen gibt. Ist ja bei anderen
> Sachen, die es in C nicht gibt, auch so.

Ja, stimmt.

Ich denke aber, das ist quasi eine Naturnotwendigkeit, denn
keine Programmiersprache kann ALLE Konstrukte, die irgendwann
mal gebraucht werden, gleichermaßen einfach und elegant
bereitstellen.
Man muss sich also auf einen gewissen Kernbereich beschränken,
und alles, was da nicht dazugehört, geht eben nur umständlicher.


>> Es ging mir nicht darum, dass das Sprachelement in manchen
>> Fällen hübsch und nett sein kann (das gestehe ich ja zu) --
>> es ging darum, dass der Schaden meiner Meinung nach den
>> Nutzen weit überwiegt und dass es deshalb sehr wohl sinnvoll
>> ist, die Verwendung zu verbieten.
>
> Das sehe ich eben anders. Ich finde es recht unsinnig, ein
> existierendes Sprachfeature an einer Stelle, wo es die
> sinnvollste Lösung wäre, nur deshalb nicht einzusetzen,
> weil man es für böse erklärt hat.

Jein. Ich verstehe Deinen Standpunkt, aber ich teile ihn
nicht (vollständig).

Du setzt einen verständigen Programmierer voraus und
betrachtest den konkreten Einzelfall, und unter der Prämisse
verstehe ich Deine Schlussfolgerung.

Allerdings blendest Du zwei Fragen aus:
1. Warum wurde goto "für böse erklärt"?
2. Liegt tatsächlich immer der Fall des verständigen
   Programmierers vor, der einen guten Grund für genau
   diese "goto" hat?

> Programmierung ist ein kompliziertes Handwerk. Da sind
> manchmal auch Werkzeuge sinnvoll, mit denen nur Experten
> richtig umgehen können.

Ja.

> Für eine CNC-Fräse muss man auch erstmal lernen, wie man sie
> benutzt. Das heißt aber nicht, dass man deshalb alle - auch
> die, die den Umgang damit gelernt haben - zwingen sollte,
> stattdessen alles mit der Feile zu bearabeiten.

Richtig, nein.

> Den Azubi, der gestern angefangen hat, lässt man aber besser
> nicht an die Maschine. Klar, ist ein etwas überzogener
> Vergleich, [...]

Neinnein, der ist sehr passend; er zeigt nämlich das Problem:
Die "Feile" der Softwerkerei existiert nicht, denn darunter
würde ich eine Sprache verstehen, die hinsichtlich Portabilität,
Eignung für Systemprogrammierung und Effizienz ungefähr (!)
vergleichbar mit C, aber einfacher zu handhaben ist.

Wenn ich eine ECHTE Alternative zu C hätte, würden mich die
Macken von C nicht interessieren -- aber es gibt ja keine.
(Zumindest kenne ich keine.)


>>> Das hat auch keiner behauptet. Aber umgekehrt sollte man
>>> auch nicht alles, was man in der Schule gelernt hat,
>>> unreflektiert übernehmen und zum Dogma machen.
>>
>> Dass das eine handfeste Beleidigung ist, ist Dir bewusst?
>
> Wo du da eine Beleidigung zu sehen glaubst, vermag ich nicht
> zu erkennen.

Man kann das lesen als "Wer nachdenkt, ist sowieso meiner
Meinung, und wer anderer Meinung ist, hat nur nicht selber
nachgedacht, sondern plappert nach, was ihm eingetrichtert
wurde."

> Es war jedenfalls nicht meine Absicht, irgendwen zu beleidigen.

Schon in Ordnung.


>> Und ich darf dabei auch zu anderen Ergebnissen kommen als Du,
>> und ich darf diese abweichende Meinung sogar öffentlich
>> vertreten.
>
> Natürlich. Nur habe ich bei den meisten von denen, die goto
> vehement ablehnen,

Hmm. Ich lehne es nicht vehement ab.
Ich verstehe nur nicht, warum man Witze über Leute macht, die
es tun.

Ich habe übrigens erst vorhin, anlässlich dieser Diskussion
mal nachgesucht und dabei festgestellt, dass Tcl gar nicht
über "goto" verfügt. Mangels Bedarf wusste ich das bisher
gar nicht. Gibts einfach nicht -- und ich habe es nie vermisst.

Ist Ousterhout ein Ignorant, Depp, Kleingeist,... weil er
goto nicht in Tcl aufgenommen hat?


> nicht den Eindruck, dass das aufgrund  selbst gebildeter
> Meinung passiert.

Hmm. Wahrscheinlich bin ich voreingenommen.

Ich bin PASCAL-sozialisiert. Als ich vor 25 erstmalig
einen Anlauf versucht habe, C zu lernen, fand ich C einen
riesengroßen Haufen unsinnig komplizierter, unlesbarer
Sch...e.
Und natürlich wurde ich in einschlägigen Diskussionen
"PASCAL vs. C" immer als der ignorante Blödmann hingestellt,
der einfach viel zu dumm ist, die göttlichen Segnungen
von C zu verstehen.

In der Zwischenzeit habe ich Tcl/Tk entdeckt und war damit
lange hochzufrieden; dann kam wieder mehr Pascal in Gestalt
von Free Pascal, nebenbei hatte ich auch Einblick in die 
Steuerungsprogrammierung; nicht zu vergessen die Automaten-
theorie, die man an der Uni gehört hatte.

Jetzt unternehme ich (wegen der Mikrocontroller) wieder
einen Anlauf, C zu lernen, und -- TATAA! -- finde es immer
noch eine riesengroße unlesbare Sonderzeichen-Schotterwüste.

Im Unterschied zu früher habe ich jetzt aber ein viel
größeres Hintergrundwissen (nicht zuletzt übrigens dank
dieses Forums) und bin in Diskussionen renitenter.

Ich will hier nicht in die Details gehen, aber ich gewinne
zunehmend die Auffassung, dass die tatsächlichen Stärken
von C (also die Eigenschaften, die C zu der Schlüsselrolle
verholfen haben, die es immer noch hat) relativ wenig mit
den Dingen zu tun haben, die "normale" C-Programmierer so
vehement an "ihrer" Sprache verteidigen.

Etwas boshafter ausgedrück: Der durchschnittliche C-
Programmierer verteidigt C mit all seinen Eigenheiten
nur deshalb, weil er gar nicht im Detail begriffen hat,
was wirklich gut und was wirklich schlecht daran ist ;)


> Possetitjel schrieb:
>> Wenn es Fälle gäbe, in denen goto NOTWENDIG, d.h.
>> UNVERZICHTBAR ist, dann könnte man ja darüber reden.
>
> Zwingend notwendig sind nur sehr wenige Sprachfeatures
> (auch Brainfuck ist Touring-vollständig).

Auf DAS Argument habe ich die ganze Zeit gewartet :)


> Deshalb muss man ja nicht gleich alles andere abschaffen.

Zum einen: Nicht "alles andere" sondern nur das Überflüssige :)

Zum anderen: Nicht "abschaffen", sondern "nicht in die Sprache
aufnehmen".
Sprachstandards wachsen nicht auf Bäumen, die ab und an
ausgeästet werden müssen -- wenn etwas in der Sprachdefinition
drinsteht, dann hat es da jemand aktiv hineingeschrieben, der
es für einen tollen Einfall gehalten hat.

Es geht mir gar nicht darum, K&R nachträglich, aus dem
sicheren Abstand von 50 Jahren zu kritisieren. Das meine
ich gar nicht.

Es geht mir um genau die andere Richtung: Manche Prioritäten
haben sich im Laufe der Zeit verschoben. Dazu gehört zum
Beispiel, dass die Konstrukte nicht mehr so compilerfreundlich
formuliert sein müssen, wie es damals war, weil die Compiler-
technik weiter ist und die Compiler viel besser optimieren
können. Zahlreiche C-Hacks sind somit überflüssig, weil der
Compiler auch aus der Langform erkennen kann, wie er das in
kurzen und effizienten Maschinencode umformen kann.

Dazu gehört auch, dass die absolute Anzahl Programmierer sehr
viel größer ist als damals und der Quelltext nicht nur zur
Mensch-Maschine-Kommunikation dient, sondern viel stärker zur
Mensch-Mensch-Kommunikation eingesetzt wird, als es früher
der Fall war. Der Sonderzeichen- und Operatorwahn, der in C
ausgelebt wird, ist unter wahrnehmungspsychologischen Aspekt
einfach kontraproduktiv.
Es genügen Grundkenntnisse der Codierungstheorie, um zu
erkennen, dass eine Syntax, die sowohl "a=b" als auch "a==b"
in identischem Kontext zulässt, ein schlechter Einfall ist.

von Einer K. (Gast)


Lesenswert?

Possetitjel schrieb:
> Allerdings blendest Du zwei Fragen aus:
> 1. Warum wurde goto "für böse erklärt"?
> 2. Liegt tatsächlich immer der Fall des verständigen
>    Programmierers vor, der einen guten Grund für genau
>    diese "goto" hat?

Zu 1:
Diese Gegebenheiten, welche zum "böse" geführt haben gibt es in C/C++ 
überhaupt nicht. Noch nicht mal im Ansatz. Und damit ist das ein totes 
Argument.

Zu 2:
In dem Satz steckt ein "immer"!
Und da es auch Idioten und Stümper gibt, wird es eben nicht "immer" 
einen Guten Grund geben. Aber das gilt auch für "ALLE" anderen 
Sprachmittel, denn mit denen kann man auch Mist bauen.

PS:
Dein heiß geliebtes Pascal (ich mag es auch) hat ebenfalls ein Goto 
eingebaut.

von Possetitjel (Gast)


Lesenswert?

Markus F. schrieb:

[100 gotos im bisherigen Leben]
> Tatsächlich war sicher deutlich mehr als die Hälfte
> davon kein eigener Code, sondern der Pfusch anderer
> Leute, die vor lauter Verschachtelung am Ende vergessen
> haben, allokierte Ressourcen frei zu geben. Wenn man
> so was reparieren muss, ohne gleich alles neu zu
> schreiben (und damit die gesamte Testmaschinerie
> anzuwerfen), ist goto Gold wert.

Das ist interessant, dass Du das so schreibst, und die
Verwendung von goto in den Kontext von Verschachtelungen
stellst.
Weiter oben schrieb Rolf, Hilfsvariablen (innerhalb von
Verschachtelungen) seien für ihn nur Krücken, die er
nach Möglichkeit vermeide.

Ich finde das bemerkenswert, weil ich i.d.R.
Verschachtelungen vermeide und ggf. Hilfsvariablen verwende.
(Die automatentheoretische Begründung dafür ist vielleicht
auch keine echte Begründung und ziemlich esoterisch.)


> Was mich stört ist der sture Dogmatismus, der hier
> durchscheint.

Naja, was heisst Dogmatismus? Ist Dein Mathelehrer aus dem
Leistungskurs auch dogmatisch, der behauptet hat, JEDE
quadratische Gleichung hätte GENAU zwei Lösungen (die u.U
auch zusammenfallen können)?

Nach meinem (lückenhaften) Kenntnisstand trafen damals, als
die "strukturierte Programmierung" aufkam (die generell auf
goto verzichten will), zwei Dinge aufeinander: Einerseits
die Beobachtung von Dijkstra, dass die Häufigkeit von goto
negativ mit der Codequalität korreliert, und andererseits
die Erkenntnis, dass es auch aus theoretischer Sicht möglich
ist, vollständig auf goto zu verzichten.

Gerade der letzte Punkt ist extrem interessant: Es geht beim
Verzicht auf goto gerade NICHT darum, einfach ein Sprach-
konstrukt der Hochsprache durch ein anderes zu ersetzen, das
letztlich wieder zum selben Maschinencode führt -- sondern
es geht darum, dass man von allen denkbaren Ablaufgraphen
alle aussondern kann, die bestimmten Regeln widersprechen,
und TROTZDEM noch alles berechnen kann, was berechenbar ist.

Dass das nicht nur akademisches Geschwätz ist, sondern auch
in der Praxis funktioniert, wird von Tcl bewiesen; dort gibt
es schlicht kein goto.
Tcl hat sicher zahlreiche Macken und Schwächen, aber
ausgerechnet das Fehlen von goto würde ich nicht dazu
zählen. Man braucht es nicht.

Ich sehe nicht, was daran dogmatisch ist. (Vielleicht eine
Folge von Betriebsblindheit...)

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Possetitjel schrieb:
[...]

Du hast aber schon einen Hang zur epischen Breite, oder ;-)

Possetitjel schrieb:
> "for" und "Eleganz" ist ein inhärenter Widerspruch. ;)

ceterum censeo, die for-loops in Lisp sind wesentlich eleganter. Aber an 
Fortran kommt nix heran

von W.S. (Gast)


Lesenswert?

Possetitjel schrieb:
> Nach meinem (lückenhaften) Kenntnisstand trafen damals, als
> die "strukturierte Programmierung" aufkam (die generell auf
> goto verzichten will), zwei Dinge aufeinander: Einerseits
> die Beobachtung von Dijkstra, dass die Häufigkeit von goto
> negativ mit der Codequalität korreliert, und andererseits
> die Erkenntnis, dass es auch aus theoretischer Sicht möglich
> ist, vollständig auf goto zu verzichten.

Ach wo. Vielleicht bist du bloß zu jung (kann ja mal passieren..)

Damals hatte ein typischer Homecomputer einen residenten 
Basic-Interpreter im ROM - und das war damals da klassische interaktive 
Basic: was man ohne Zeilennummer eintippt, wird ausgeführt, was man mit 
Zeilennummer eintippt, wird im gerade geladenen Programm gespeichert. 
Das war die Zeit, wo man ohne GOTO schlichtweg nicht auskam.
Nochmal zum tief Einsinken: das GOTO war damals in Basic 
lebensnotwendig.

Selbst beim ersten IBM-PC war Basic der Anfang von allem, wenn das BIOS 
kein BS auf der Floppy fand, wurde schlichtweg ins Microsoftsche Basic 
verzweigt. Nun komme bitte keiner mit CP/M, wo es schon am Ende der 70er 
keinen residenten Basicinterpreter gab. Diese Gefilde waren damals 
unerschwinglich. 16 K RAM hatten damals ein halbes Vermögen gekostet, 
von 64 K ganz zuschweigen.

Mit dem Vordringen besser strunturierter Programmiersprachen - im 
Klartext Pascal (HISOFT auf dem ZX-Spectrum so um 1984..86 etwa, hab's 
nicht auswendig gelernt) kam ein Paradigmenwechsel. Man hatte plötzlich 
Prozeduren und Funktionen, die echte Argumente haben konnten und es gab 
Syntaxelemente, die zum Strukturieren geeignet waren wie repeat xxx 
until yyy; oder do...while.

Das war für alle jungen Burschen, die in Basic sozialisiert waren, etwas 
völlig neues und grundanderes! Um das den Leuten einzuprügeln, kamen 
Sprüche auf wie "GOTO ist böse" und dergleichen. Das war auch bloß ein 
Dogmatismus, wenngleich zum Anstoßen des Umdenkens wohl damals 
notwendig.

Das alles hat mit Dijkstra nichts zu tun. Allerdings kann man 
beobachten, daß gerade in den Kreisen der C-Leute derartige Dinge wie 
Goto oder globale Variablen noch immer ausgesprochen fanatisch 
diskutiert werden. Mittlerweile sollte sich doch in solchen Dingen die 
Hitzköpfigkeit gelegt haben und der Erkenntnis gewichen sein, daß es in 
jeder Programmiersprache, die mit Anweisungen arbeitet, eben auch sowas 
wie einen unbedingten Sprung geben soll. Das gehört zur Vollständigkeit 
dazu.

W.S.

von Possetitjel (Gast)


Lesenswert?

Michael R. schrieb:

> Du hast aber schon einen Hang zur epischen Breite, oder ;-)

Hmpf. Treffer, versenkt!


> Possetitjel schrieb:
>> "for" und "Eleganz" ist ein inhärenter Widerspruch. ;)
>
> ceterum censeo, die for-loops in Lisp sind wesentlich
> eleganter.

Nun ja, was ich auf die Schnelle gesehen habe, erinnert
doch stark an "foreach" in Tcl -- und dessen Eleganz
steht ja wohl außer Frage :)


> Aber an Fortran kommt nix heran

Über Geschmack lässt sich nicht streiten...

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

W.S. schrieb:
> Mittlerweile sollte sich doch in solchen Dingen die
> Hitzköpfigkeit gelegt  [...] haben

Tja... wie man sieht, offensichtlich nicht.

Possetitjel schrieb:
>> Aber an Fortran kommt nix heran
> Über Geschmack lässt sich nicht streiten...

Aber wenn schon Fortran 66, "to compile loops like god meant them to be"

von Possetitjel (Gast)


Lesenswert?

Nop schrieb:

> Possetitjel schrieb:
>
>> Wenn man ernsthaft darüber diskutieren kann, die Verwendung
>> eines formalsprachlich korrekten Konstruktes zu verbieten,
>> dann ist die Sprachdefinition schlecht.
>
> Nein, sondern dann wurde die Sprache eben von Profis entworfen,

"Profis haben die Titanic gebaut, ein Amateur die Arche Noah."


> Wenn ich mir ansehe, wie man in Pascal üblicherweise gestackte
> Fehlerbehandlung ohne goto macht,

Über die Pascal-vs.-C-Debatten bin ich 20 Jahre hinaus; das
koche ich nicht wieder auf. Aktuelle Referenz wäre Tcl.
Dort gibt es schlicht kein goto, und ich habe es nie vermisst.

> oder auch Ausstieg aus geschachtelten Schleifen, dann ist
> das noch unübersichtlicher. Das läuft dann nämlich auf
> tief geschachtelte ifs, Code-Duplikation und/oder absurde
> Hilfs-Variablen hinaus.

Das ist bemerkenswert, denn Du bist schon der Dritte, der
goto in den Kontext von Verschachtelungen stellt.

"Tief geschachtelte ifs": Vermeide ich generell; da mache
ich zu viele Fehler (nicht wegen der Syntax, sondern aus
inhaltlichen Gründen). Ich verwende tendenziell lieber
einfache ifs und Hilfsvariablen.

"Code-Duplikationen": Pascal und Tcl kennen glücklicherweise
lokale Prozeduren bzw. Funktionen -- im Gegensatz zu C.
Doppelter Code ist daher i.d.R. unnötig.

Und zum Thema "absurde Hilfsvariablen": Die Absurdität liegt
durchaus im Auge des Betrachters. Es gibt sehr wohl einen
automatentheoretischen Blickwinkel, unter dem die Hilfs-
variablen nicht nur nicht absurd, sondern im Gegenteil
völlig natürlich sind.


> Das goto, worauf sich Dijkstra damals bezogen hat, und
> was tatsächlich zu Spaghetti geführt hat, war nämlich
> ein gänzlich anderes. Damals konnte man noch anhand
> absoluter Zeilennummern

Zeilennummern oder Labels macht keinen grundsätzlichen
Unterschied.


> quer durch das ganze Programm springen.

Das macht auch nur einen graduellen, keinen prinzipiellen
Unterschied. Insofern teile ich Deine Auffassung vom
"gänzlich anderen goto" nicht.

Ich gestehe aber zu, dass die schlimmsten Macken des
klassischen goto in C verboten sind. (Auch graduelle
Unterschiede sind Unterschiede; auch ein gradueller
Fortschritt ist ein Fortschritt. Soweit gehe ich mit.)


> Das hat so gut wie nichts mit C-goto zu tun, was man nur
> innerhalb einer Funktion benutzen kann,

Der Teller mit Spaghetti ist etwas kleiner, aber Spaghetti-
code produzieren kann man immer noch. Die Komplexität dessen,
was man in einer Funktion unterbringen kann, ist durch die
Sprache nicht beschränkt.


> Richtig ist aber auch, daß Rückwärtssprünge mit goto
> bedenklich sind, auch in C. Das kann man meistens mit
> einer while-Schleife umgehen, die einen Zustandsautomaten
> enthält. Der ist dann auch übersichtlicher. So mache ich
> jedenfalls algorithmische Rückwärtssprünge, sofern ist
> nicht das letzte bißchen an Performance gerade an der
> Stelle brauche. Schon weil ein Zustandsautomat ein Idiom
> ist, was jeder nachfolgende Programmierer kennt und sofort
> versteht.

Ich bin beeindruckt. Genau das ist nämlich der Knackpunkt:
Der Zusammenhang zwischen den zugelassenen Sprachkonstrukten
und den (damit) formulierbaren Automatenstrukturen.

Um hier nochmal auf die "absurden Hilfsvariablen" zurück-
zukommen: Das sind einfach die Zustandsvariablen eines
passenden endlichen Automaten.
Und ich persönlich finde es auch schöner, diesen Zuständen
einen Namen zu geben und sie explizit per Anweisung zu
setzen, als sie in der Steuerstruktur des Programmes zu
verstecken. Der zugehörige Automat ist nämlich trotzdem
noch da -- er ist nur nicht so gut zu erkennen.

Das ist aber persönliche Macke, das gebe ich zu.

> Selbst Vorwärtssprünge mit goto sind in den allermeisten
> Fällen auf Fehlerbehandlung begrenzt. Computed goto, also
> goto anhand eines Label-Arrays per Index, ist leider immer
> noch nicht Teil des C-Standards (GCC und Clang können es).
> Das kann man aber algorithmisch gut gebrauchen, wenn es
> auf Performance ankommt. Sowas betrifft etwa Interpreter,
> Python sei genannt.

Jetzt sind wir schon beim anderen Thema: "Switch" verbieten! :)

von 900ss (900ss)


Lesenswert?

Markus F. schrieb:
> Nicht, weil ich's unbedingt gebraucht hätte, sondern weil es in der
> Situation die einfachere, leichter lesbare, einfach bessere Lösung war.

Genau! Das ist genau DER Grund, goto zu benutzen.

In diesem Beispiel, in dem auch noch eine Variable genutzt werden muss:

Beitrag "Re: Lesbarer ProgrammCode"

wäre ein goto angebracht.
Was macht eigentlich break in dem Beispiel? Ist nichts anderes als ein 
goto, wenngleich ein eingeschränktes.

Ein goto in solch wenigen Situationen gezielt eingesetzt ist ein gutes 
goto.

Wer mit goto Spagetticode erzeugt, hat in der professionellen 
Programmierung nicht verloren.
Leider halten sich nicht alle dran ;)

Und nein, ich darf auch kein goto verwenden. Nicht einmal ein break um 
eine Schleife zu verlassen. Ernsthaft. Der Rulechecker würde meckern und 
ich müsste es ändern wenn ich break/goto verwende.  %-o  =Vor die Stirn 
klatsch=

Ich nutze dann Steuervariablen wie in dem aufgeführten Beispiel gezeigt. 
Ich finde es wirklich dummes Zeug.

: Bearbeitet durch User
von Possetitjel (Gast)


Lesenswert?

900ss D. schrieb:

> Markus F. schrieb:
>> Nicht, weil ich's unbedingt gebraucht hätte, sondern weil
>> es in der Situation die einfachere, leichter lesbare,
>> einfach bessere Lösung war.
>
> Genau! Das ist genau DER Grund, goto zu benutzen.

Es ging (mir) doch gar nicht darum, dass manchmal wirklich
gute Gründe gibt, goto zu verwenden.

Es ging (mir) um die Frage, ob Menschen, die goto verbieten,
in jedem Falle dogmatisch, beschränkt, kleingeistig, ... sind,
oder ob es vielleicht auch GUTE Gründe dafür gibt.

Klassischer Fall einer Güterabwägung: Ist das, was man durch
das Verbot gewinnt, wichtiger als das, was man verliert?


> Was macht eigentlich break in dem Beispiel? Ist nichts
> anderes als ein goto, wenngleich ein eingeschränktes.

Die Einschränkung ist aber gerade das, worum es geht!

Mit break kann man z.B. nicht rückwärts springen -- mit
goto dagegen kann man eine parasitäre Schleife basteln.


> Und nein, ich darf auch kein goto verwenden. Nicht einmal
> ein break um eine Schleife zu verlassen. Ernsthaft.

Kein break?! Warum das denn?

von 900ss (900ss)


Lesenswert?

Possetitjel schrieb:
> goto dagegen kann man eine parasitäre Schleife basteln.

Genau das kann man ja am Basteltisch machen wer möchte. In 
professionellem Code hat das nichts zusuchen. goto gezielt in wenigen 
sinnvollen Stellen einsetzen ist ok.

Possetitjel schrieb:
> Kein break?! Warum das denn?

Keine Ahnung, begründet würde keine Regel. Es gibt noch mehr so Blödsinn 
in dem Regelwerk.

: Bearbeitet durch User
von Possetitjel (Gast)


Lesenswert?

900ss D. schrieb:

> Possetitjel schrieb:
>> goto dagegen kann man eine parasitäre Schleife basteln.
>
> Genau das kann man ja am Basteltisch machen wer möchte.

???

Niemand MÖCHTE einen Fehler machen -- aber trotzdem werden
dauernd welche gemacht!


> In professionellem Code hat das nichts zusuchen.

Wenn EIN goto erlaubt ist, um aus geschachtelten Schleifen
herauszuspringen, dann sind auch ZWEI gotos zulässig, um
aus zwei (unterschiedlichen, unabhängigen) Blöcken
geschachtelter Schleifen herauszuspringen.

Jetzt musst Du nur noch die Labels verwechseln, und die
ungewollte Schleife ist fertig.


> Possetitjel schrieb:
>> Kein break?! Warum das denn?
>
> Keine Ahnung, begründet würde keine Regel. Es gibt noch
> mehr so Blödsinn in dem Regelwerk.

Was ich wissen wollte: Welches Regelwerk ist es denn?
MISRA wohl nicht?!

von p41145 (Gast)


Lesenswert?

900ss D. schrieb:
> Possetitjel schrieb:
>> Kein break?! Warum das denn?
>
> Keine Ahnung, begründet würde keine Regel. Es gibt noch mehr so Blödsinn
> in dem Regelwerk.

Das mit einem Einstiegpunkt und einem Ausstiegpunkt gilt ja auch für 
Schleifen ;-)

"for" soll verwendet werden für eine feste Anzahl an Durchläufen --> 
break hier unsinnig

"while" oder "do while" sind bedingte Schleifen, bei dem der Ausstieg 
schon in der while steht --> auch kein break erforderlich

Mit ein paar breaks drin wird sowas sehr schnell unstrukturiert. So hat 
man die Gewissheit, dass die Schleife ganz oder gar nicht abläuft.

"switch case" sind vielleicht auch verboten? Oder halt mit der Regel 
immer ein break pro case? Macht ja manchmal Sinn den break an einer 
Stelle wegzulassen, was aber auch ein wilden Sprung gleicht. Stattdessen 
könnte man da ja wirklich zum Goto greifen, damit das sofort auffällt 
;-)

von Possetitjel (Gast)


Lesenswert?

Arduino F. schrieb:

> Diese Gegebenheiten, welche zum "böse" geführt haben

Also, vielleicht muss ich doch mal was klarstellen. Mir
hat niemals irgend jemand erzählt, goto sei "böse".

Ich habe gelernt, dass
1. Spaghetticode durch übermäßige Verwendung von goto
   entsteht;
2. "strukturierte Programmierung" ohne goto auskommt
   und sich auf die drei Elemente
   - Sequenz,
   - Verzweigung und
   - Schleife
   beschränkt;
3. durch theoretische Betrachtungen gesichert ist, dass
   man in jedem Falle auch mit den genannten drei Elementen
   auskommt, goto also im Prinzip nie wirklich benötigt.

> gibt es in C/C++ überhaupt nicht. Noch nicht mal im Ansatz.

Das stimmt NUR dann, wenn das Sprungziel ("Label") stets nur
NACH der goto-Anweisung stehen darf.

Ist das so?

> Zu 2:
> In dem Satz steckt ein "immer"!
> Und da es auch Idioten und Stümper gibt,

Nicht nur.

Es gibt auch Anfänger, denen eine Aufgabe aufgedrückt wird,
die sie völlig überfordert, Programmierer, die halb zwei in
der Nacht vor der Auslieferung noch die Kastanien aus dem
Feuer holen sollen, oder Programmierer, die in einem Team,
in dem es niemand länger als ein halbes Jahr aushält, zu
einem brauchbaren Ergebnis kommen wollen.

Die Welt ist nicht so einfach, wie Du sie gern hättest.

> wird es eben nicht "immer" einen Guten Grund geben. Aber
> das gilt auch für "ALLE" anderen Sprachmittel, denn mit
> denen kann man auch Mist bauen.

Das ist im Prinzip richtig.

Die entscheidenden Fragen sind nur: Wie groß ist der Mist,
den man baut, und wie schnell fällt er auf?

Das Problem an goto ist, dass man damit (im Gegensatz zu
den anderen Steueranweisungen) die Ablaufstruktur beliebig
kaputtmachen kann. Goto ist zuviel Macht in einer einzelnen
Anweisung.

> PS:
> Dein heiß geliebtes Pascal (ich mag es auch)

Die Stichelei ist unnötig. Pascal hat andere Macken als C,
aber sicher genauso viele.


> hat ebenfalls ein Goto eingebaut.

Sicher -- und ich frage mich ernsthaft, warum eigentlich.


Tcl hat übrigens kein goto :)

von Druckertreiber (Gast)


Lesenswert?

Possetitjel schrieb:
> goto also im Prinzip nie wirklich benötigt.
Im Prinzip nie, man kann schließlich auch mit der Kirche ums Dorf.

Was m.E. in der Diskussion bisher nicht berüksichtigt wurde, ist, dass 
ein (C-)Code auch das Compilat einer anderen Sprache bzw. eines 
Programms sein kann. Und damit nicht die Lesbarkeit im Vordergrund 
steht.
Z.B. bei der Codegenerierung von einer graphischen UML-Programmierung. 
Die Pfeile in einem UML-Diagramm sind ja letztlich Gotos. Das mit 
Funktionen, IF-Abfragen, EXITs, BREAKS etc. zu emulieren kann die 
Codegenerierung deutlich komplizierter machen.

Damit ist auch klar, dass solche Konstrukte für Universalsprachen wie C 
oder Pascal eben unverzichtbar sind.

von Markus F. (mfro)


Lesenswert?

Possetitjel schrieb:
> Tcl hat übrigens kein goto :)

Tcl ist auch keine systemnahe, hochoptimierende Programmiersprache.

Tcl ist ein Plastiklöffel.

von Einer K. (Gast)


Lesenswert?

Possetitjel schrieb:
> Die Welt ist nicht so einfach, wie Du sie gern hättest.
Ach? Nein?
> Goto gehört abgeschafft.
Wer will denn hier die Menschheit (zumindest die Programmierer) in ein 
Korsett zu pressen?

Ja, ich stimme dir zu:
Die Welt ist nicht so einfach, wie Du sie gern hättest.

Es gibt Code, welcher sich mit Gotos einfacher strukturieren lässt, als 
mit zwanghafter Goto Vermeidung. Das wurde hier schon mehrfach genannt.
Selbst du hast da zugestimmt.

Alte Regel:
Hat man 2 mögliche (fehlerfreie) Varianten, dann wählte man die 
einfachere und übersichtlichere.

Im Klartext:
Du möchtest, ausschließlich aus Dogmatismus, einen höheren/unnützen 
Komplexitätsgrad erzwingen.


Possetitjel schrieb:
> oder Programmierer, die in einem Team,
> in dem es niemand länger als ein halbes Jahr aushält, zu
> einem brauchbaren Ergebnis kommen wollen.

Ich kann nur froh sein, dass sich in meinem Arbeitsumfeld nicht solche 
"Priester des Absoluten", solche Dogmatiker, wie du befinden.

Und ich kann auch nur jedem anderen wünschen, dass er nicht so einen wie 
dich als Vorgesetzten vor die Nase gesetzt bekommt.
Denn sonst ist man fix bei:
> einem Team, in dem es niemand länger als ein halbes Jahr aushält

So...
Und damit ist das Goto Thema,jetzt und hier, für mich durch.

von Johann L. (gjlayde) Benutzerseite


Angehängte Dateien:

Lesenswert?

Possetitjel schrieb:
> Wenn man ernsthaft darüber diskutieren kann, die Verwendung
> eines formalsprachlich korrekten Konstruktes zu verbieten,
> dann ist die Sprachdefinition schlecht.

In diesem Falle: nein, denn die Diskussion hier hat die "Lesbarkeit" des 
Codes als Horizont.

Es gibt jedoch auch Fälle, wo die Lesbarkeit schlicht keine Rolle 
spielt, nämlich bei auto-generiertem Code, und viele der Leser hier 
verwenden tatsächlich solchen Code, auch wenn ihnen das nicht klar ist 
[*].

Die Folgerung

Lesbarkeit => Kein goto => goto ist überflüssig => goto verbannen

bricht also bereits unter der nicht immer erfüllten Annahme zusammen, 
dass Lesbarkeit immer eine Rolle spiele.

[*] Ein Beispiel ist GCC, der aus der Maschinenbeschreibung u.a. C/C++ 
Code erzeugt, um bestimmte Bäume möglichst schnell zu durchsuchen.  An 
jedem Knoten sind andere Entscheidungen zu treffen, und während des 
Traversierens werden Eigenschaften des gewählen Pfades eingesammelt, 
vergleichbar mit Capturing bei regulären Ausdrücken.

In diesem Fall zählt:

1) An erster Stelle Host-Performance, also die Zeit, die GCC selbst zum 
Compilieren braucht.  Üblicherweise werden solche auto-generierten Teile 
genauen Benchmarks unterzogen, um beste Host-Performance zu erhalten, 
und die gewählte Expansion daran angepasst.

2) An zweiter Stelle Wartbarkeit, Nachvollziehbarkeit und Lesbarkeit des 
Generators.

3) Erst an dritter Stelle die Lesbarleit des generierten Code.  Normal 
liest schlichtweg niemand diesen Code.

> Und genau das ist auch meine (Außenseiter-)Meinung.

Wer keine Ahnung hat bildet sich stattdessen eine Meinung ;-/

> Da man aber i.d.R. nicht die Macht hat, das Übel an der
> Wurzel zu packen, beschränkt man sich auf die Symptom-
> behandlung und verbietet eben die Verwendung von goto.

Es gibt eben auch Nischen, wo goto sinnvoll ist; wie im gezeigten 
Beispiel.

Dass diese Nischen jenseits des Horizonts "normaler" Anwender sind, ist 
nicht verwunderlich; aber dadurch verschwindet nicht die Berechtigung in 
der Nische.

Der angehängte Code ist von einem avr-gcc, Backends wie x86, arm oder 
powerpc erzeugen noch wesentlich größere Bäume.

von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

Hier mal ein Beispiel, wie goto die Les- und Wartbarkeit erhoeht:
1
int fancy_device_driver(void)
2
{
3
    uint8_t *mem_1;
4
    uint16_t *mem_2;
5
    uint32_t *mem_3;
6
7
    int ret_val = 0;
8
9
10
    mem_1 = malloc(10);
11
    if (mem_1 == NULL) {
12
        ret_val = -1;
13
14
        goto mem_1_alloc_fail;
15
    }
16
17
    /*  do fancy stuff  */
18
19
    mem_2 = malloc(23 * sizeof(uint16_t));
20
    if (mem_2 == NULL) {
21
        ret_val = -2;
22
23
        goto mem_2_alloc_fail;
24
    }
25
26
    /*  do fancy stuff  */
27
28
    mem_3 = malloc(47 * sizeof(uint32_t));
29
    if (mem_3 == NULL) {
30
        ret_val = -3;
31
32
        goto mem_3_alloc_fail;
33
    }
34
35
    /*  do fancy stuff  */
36
37
38
    free(mem_3);
39
40
mem_3_alloc_fail:
41
    free(mem_2);
42
43
mem_2_alloc_fail:
44
    free(mem_1);
45
46
mem_1_alloc_fail:
47
    return ret_val;
48
}

Jetzt moege mir doch bitte einer von denen, die nach einem Verbot/der 
Ausmerzung von goto bruellen, zeigen, wie sie das ohne goto auch nur 
ansatzweise so sauber hinbekommen. Und dann schaut auch mal was mit 
eurem Code passiert, wenn ihr noch einen oder zwei neue Speicherbloecke 
allokiert. Ohne goto explodiert der Code und es entsteht viel doppelter 
Code um den Speicher wieder freizugeben (je speicher 2x free: 1x fuer 
den Fehlerfall, und 1x fuer den Fall das alles geklappt hat). Mit goto 
braucht man nur 1x free pro Speicher, egal ob Fehler oder nicht.

von Possetitjel (Gast)


Lesenswert?

Markus F. schrieb:

> Possetitjel schrieb:
>> Tcl hat übrigens kein goto :)
>
> Tcl ist auch keine systemnahe,

Das stimmt.


> hochoptimierende Programmiersprache.

Das stimmt ziemlich sicher nicht. Die Performance von
Tcl ist nicht so schlecht, wie häufig behauptet wird.


> Tcl ist ein Plastiklöffel.

Was soll das?

von Possetitjel (Gast)


Lesenswert?

Arduino F. schrieb:

> Possetitjel schrieb:
>> Die Welt ist nicht so einfach, wie Du sie gern hättest.
> Ach? Nein?

Nein.


>> Goto gehört abgeschafft.

Na jetzt geht's aber los. Zitate fälschen ist -- im Gegensatz
zu goto -- aber WIRKLICH böse. Den hier "zitierten" Satz habe
ich nicht geschrieben.


> Wer will denn hier die Menschheit (zumindest die
> Programmierer) in ein Korsett zu pressen?

Ich nicht. Ich habe nur die Frage aufgeworfen, wieso Witze
über die Leute gemacht werden, die in ihrem Wirkungsbereich
goto verbieten.


> Es gibt Code, welcher sich mit Gotos einfacher strukturieren
> lässt, als mit zwanghafter Goto Vermeidung. Das wurde hier
> schon mehrfach genannt.
> Selbst du hast da zugestimmt.

Ja, dabei bleibe ich auch.

> Alte Regel:
> Hat man 2 mögliche (fehlerfreie) Varianten, dann wählte man
> die einfachere und übersichtlichere.

Ja. Wenn man diese Wahl hat, dann wählt man so.


> Im Klartext:
> Du möchtest, ausschließlich aus Dogmatismus, einen
> höheren/unnützen Komplexitätsgrad erzwingen.

Nein.
Es geht nicht um Dogmatismus, sondern um eine klassische
Güterabwägung: Was gewinnt man, wenn man goto verbietet,
und was verliert man?

Was man beim goto-Verbot verliert, darüber besteht weitgehend
Einigkeit. Ich vermisse eine faire Diskussion dessen, was man
gewinnt.

Auf meine Bemerkungen dazu wurde bisher nicht sachlich
geantwortet.

von Markus F. (mfro)


Lesenswert?

Possetitjel schrieb:
> Markus F. schrieb:
>
>> Possetitjel schrieb:
>>> Tcl hat übrigens kein goto :)
>>
>> Tcl ist auch keine systemnahe,
>
> Das stimmt.
>
>
>> hochoptimierende Programmiersprache.
>
> Das stimmt ziemlich sicher nicht. Die Performance von
> Tcl ist nicht so schlecht, wie häufig behauptet wird.
>

Die Performance von Tcl ist gegenüber einem optimierten C-Programm 
miserabel (nach meinen Versuchen nicht nur Faktor 2 oder so, sondern 
eher 200 bis 2000). Das soll nicht heissen, dass man es nicht gebrauchen 
kann. Man kann es gebrauchen, aber nicht für alles.

>
>> Tcl ist ein Plastiklöffel.
>
> Was soll das?

Wenn Du meinen Beitrag oben gelesen hättest, würdest Du das verstehen.

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


Lesenswert?

Kaj G. schrieb:
> Jetzt moege mir doch bitte einer von denen, die nach einem Verbot/der
> Ausmerzung von goto bruellen, zeigen, wie sie das ohne goto auch nur
> ansatzweise so sauber hinbekommen.

In anderen Sprachen mit Exceptions. ;-)

Anmerkung: auch, wenn ich diese Antwort geschrieben habe, bin ich
keiner, der „nach einem Verbot von goto brüllen“ würde. :)

: Bearbeitet durch Moderator
von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Jörg W. schrieb:
> Exceptions

autsch!

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Kaj G. schrieb:

> Jetzt moege mir doch bitte einer von denen, die nach einem Verbot/der
> Ausmerzung von goto bruellen, zeigen, wie sie das ohne goto auch nur
> ansatzweise so sauber hinbekommen.

Ich brülle zwar nicht und verwende auch kein C, ich versuche es aber 
trotzdem mal ;-) :
1
static void checked_free( void* p )
2
{
3
    if ( p )
4
        free( p );
5
}
6
7
int fancy_device_driver(void)
8
{
9
    uint8_t *mem_1 = malloc(10);
10
    /*  do fancy stuff  */
11
 
12
    uint16_t *mem_2 = alloc(23 * sizeof(uint16_t));
13
    /*  do fancy stuff  */
14
 
15
    uint32_t *mem_3 = malloc(47 * sizeof(uint32_t));
16
    /*  do fancy stuff  */
17
18
    int ret_val = 0;
19
20
    if ( mem_1 == NULL )
21
        ret_val = -1;
22
    else if ( mem_2 == NULL )
23
        ret_val = -2;
24
    else if ( mem_3 == NULL )
25
        ret_val = -3;
26
27
    checked_free(mem_3);
28
    checked_free(mem_2);
29
    checked_free(mem_1);
30
31
    return ret_val;
32
}

mfg Torsten

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


Lesenswert?

Das "checked_free" brauchst du nicht, es ist legal, free() einen
Nullzeiger zu übergeben.

Aber: du deallozierst jetzt immer alles. :-)

Wenn schon, dann
1
   if (mem_1 == NULL || mem_2 == NULL || mem_3 == NULL)
2
   {
3
      free(mem_1);
4
      free(mem_2);
5
      free(mem_3);
6
      return -42;
7
   }

Gut, der war noch einfach. :-)  Es gibt kompliziertere Fälle, bei
denen man dann wirklich sackweise Hilfsfunktionen machen müsste.

Im Sinne der „reinen Lehre“ wäre ja auch ein vorzeitiges „return“
nur ein verkapptes „goto“ und damit strikt zu vermeiden …

von Joachim B. (jar)


Lesenswert?

Torsten R. schrieb:
> ich versuche es aber
> trotzdem mal ;-) :

Torsten R. schrieb:
> uint8_t *mem_1 = malloc(10);
>     /*  do fancy stuff  */

klappt schon auf dem Papier nicht

wenn malloc(10) erfolglos war kann

Torsten R. schrieb:
> /*  do fancy stuff  */

nicht vernünftiges mehr machen falls

> /*  do fancy stuff  */

den mem brauchte!

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Joachim B. schrieb:
> Torsten R. schrieb:
>> ich versuche es aber
>> trotzdem mal ;-) :
>
> Torsten R. schrieb:
>> uint8_t *mem_1 = malloc(10);
>>     /*  do fancy stuff  */
>
> klappt schon auf dem Papier nicht

da hast Du natürlich recht!

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Jörg W. schrieb:
> Das "checked_free" brauchst du nicht, es ist legal, free() einen
> Nullzeiger zu übergeben.

Ah, ok. Ich dachte, das gilt nur für C++ delete.

> Aber: du deallozierst jetzt immer alles. :-)

Ja, dass macht das Original aber auch.

Hier die C++ Variante:
1
    // kleiner Scherz ;-)

von Possetitjel (Gast)


Lesenswert?

Johann L. schrieb:

> Possetitjel schrieb:
>> Wenn man ernsthaft darüber diskutieren kann, die Verwendung
>> eines formalsprachlich korrekten Konstruktes zu verbieten,
>> dann ist die Sprachdefinition schlecht.
>
> In diesem Falle: nein, denn die Diskussion hier hat die
> "Lesbarkeit" des Codes als Horizont.
>
> Es gibt jedoch auch Fälle, wo die Lesbarkeit schlicht keine
> Rolle spielt, nämlich bei auto-generiertem Code,

Okay.

Das ist, wenn ich Dich richtig verstehe, ein (zweites) Argument
dafür, dass man goto sowieso nicht aus dem Standard streichen
könnte -- eben weil man goto für automatisch generierten C-Code
haben will.

Das stärkt aber die Position der Leute, die die Verwendung von
goto durch Menschen per Arbeitsanweisung verbieten. Schließlich
geht es gar nicht darum, dass goto für die MASCHINE irgendwie
schädliche wäre -- sondern nur darum, dass der programmierende
MENSCH zuviel Quatsch mit dieser Anweisung anstellen kann.

Also verbietet man es dem Menschen und erlaubt es der Maschine.


>> Und genau das ist auch meine (Außenseiter-)Meinung.
>
> Wer keine Ahnung hat bildet sich stattdessen eine Meinung ;-/

Tja... mühsam ernährt sich das Eichhörnchen von den Früchten
des Waldes...:)


>> Da man aber i.d.R. nicht die Macht hat, das Übel an der
>> Wurzel zu packen, beschränkt man sich auf die Symptom-
>> behandlung und verbietet eben die Verwendung von goto.
>
> Es gibt eben auch Nischen, wo goto sinnvoll ist; wie im
> gezeigten Beispiel.

Natürlich -- das habe ich ja nie bestritten.


> Dass diese Nischen jenseits des Horizonts "normaler"
> Anwender sind, ist nicht verwunderlich; aber dadurch
> verschwindet nicht  die Berechtigung in der Nische.

Naja, das erinnert doch stark an "Spinat wird sehr schmackhaft,
wenn man ihn kurz vor dem Verzehr durch ein saftiges Schnitzel
ersetzt." :)
Es sind ja gerade die "normalen" Anwender, die hier das Verbot
von goto anprangern.

Auf der rein persönlichen Ebene verstehe ich die Verärgerung
auch; es ist halt zum Kotzen, wenn man aufgrund einer dämlichen
Festlegung ein lt. Standard legitimes und im konkreten Falle
auch angemessenes Konstrukt nicht einsetzen darf.

Die Argumentationslinie gibt ja durchaus Sinn: Die Sachlage
in C heute ist mit derjenigen zur Entstehungszeit von
"Go To statement considered harmfull" nicht vergleichbar,
weil:
1. in C zahlreiche Steueranweisungen existieren, die den
   Prinzipien der strukturierten Programmierung gehorchen,
   und diese i.d.R. von vernünftigen Programmierern auch
   eingesetzt werden;
2. das Missbrauchspotenzial von goto durch Beschränkung auf
   die aktuelle Funktion ohnehin eingeschränkt ist;
3. der Verzicht auf goto kontraproduktiv sein kann, weil
   Verwenden von goto die Lesbarkeit verbessern würde.

Dennoch bleibt für mich als Fazit: Die Apokalypse tritt
sicher nicht ein, wenn man goto verwendet -- aber sie tritt
genausowenig ein, wenn man die Verwendung durch Menschen
verbietet.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Jörg W. schrieb:
> Das "checked_free" brauchst du nicht, es ist legal, free() einen
> Nullzeiger zu übergeben.

Das ist zwar richtig, aber die (theoretischen) betrachtungen zu solchen 
Fällen gehen meist von "allokierbaren Ressourcen" aus, und das muss 
nicht immer Speicher (und daher nicht immer malloc()/free() sein. oft 
sind es auch (beliebige) Handles, und oft auch "aufeinander aufbauend", 
d.h. obigem zweiten malloc() wird ein Parameter aus dem ersten malloc() 
mitgegeben.

Ja, natürlich, das geht alles mit beliebig tief verschachtelten 
if-Schlei^H^H^H^H^H^H Bedingungen , aber lesbar ist das nicht mehr...

Jörg W. schrieb:
> Im Sinne der „reinen Lehre“ wäre ja auch ein vorzeitiges „return“
> nur ein verkapptes „goto“ und damit strikt zu vermeiden

genau! :-)

aber ich liebe "early returns". Vor allem in Kombination der 
"umgedrehten" (Perl-) Syntax "do_something if(condition)" und meinem 
geliebten "unless()"

von R. M. (n_a_n)


Lesenswert?

Vor vielen, vielen Jahren habe ich ein Programm in PIC- Assembler 
geschrieben.
Ein Kollege von mir, ein promovierter Physiker, hat sich einmal
das Listing angesehen und gemeint: GOTO sollte man doch nicht verwenden.

Manche Leute müssen wirklich immer ihre 2 Cent dazugeben.

Das waren meine 2 Cent;-)

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


Lesenswert?

R. M. schrieb:
> Ein Kollege von mir, ein promovierter Physiker, hat sich einmal
> das Listing angesehen und gemeint: GOTO sollte man doch nicht verwenden.

Kommt FORTRAN denn inzwischen ohne GOTO aus? :-)

von Joachim B. (jar)


Lesenswert?

früher (tm) gabs nur goto um einigermassen strukturiert zu programmieren 
auf dem CBM.

Heute versuche ich auch es immer wieder zu vermeiden weil es keine 
klaren Ausgänge gibt in Schleifen, man kann einfach raushüpfen und ein 
ziemliches Chaos hinterlassen, aber das geht mit Funktionsaufrufe wo 
while(1); drin steht genauso.

Zu debuggen ist das schwerer weil irgendwo der µC oder Compi stehen 
bleibt.

Auch statt wie hier goto zu meiden macht es mit tief verschachtelte IF 
Abfragen nicht besser, ich hatte es versucht sah aber ein das es sinnlos 
wird und immer schlechter lesbar.

von R. M. (n_a_n)


Lesenswert?

Jörg W. schrieb:
> Kommt FORTRAN denn inzwischen ohne GOTO aus? :-)

Das wäre eine gute Gegenfrage gewesen.
Leider fällt mir so was immer viel zu spät ein.
In diesem Fall Jahrzehnte zu spät ;-)

von Possetitjel (Gast)


Lesenswert?

Kaj G. schrieb:

> Jetzt moege mir doch bitte einer von denen, die nach
> einem Verbot/der Ausmerzung von goto bruellen,

Tut hier niemand.

> zeigen, wie sie das ohne goto auch nur ansatzweise so
> sauber hinbekommen.

Man verwendet in jedem Block zusätzliche Tests auf
ret_val == 0.

Das ist genau die Lösung mit den "abstrusen Hilfsvariablen",
von der weiter oben die Rede war. Und SO extrem abstrus kann
die Hilfsvariable nicht sein, wenn Du sie in Deiner Lösung
ohnehin benötigst.

Das Freigeben des Speichers muss man natürlich umformulieren.

> Und dann schaut auch mal was mit eurem Code passiert, wenn
> ihr noch einen oder zwei neue Speicherbloecke allokiert.

Da passiert gar nichts.
Das ist doch im Prinzip nur das klassische Pattern-Action-
Schema.

> Ohne goto explodiert der Code und es entsteht viel doppelter
> Code um den Speicher wieder freizugeben

Weder - noch.
Es entsteht nur ein geringfügiger Laufzeitnachteil, weil,
wenn eine Aktion fehlgeschlagen ist, immer noch bei allen
folgenden auf ret_val == 0 getesten und dann zum nächsten
Block gesprungen wird.
Das ist aber nur ein LAUFZEITNACHTEIL und hat nichts mit
der Lesbarkeit zu tun.

von Possetitjel (Gast)


Lesenswert?

Markus F. schrieb:

> Possetitjel schrieb:
>> Markus F. schrieb:
>>
>>> hochoptimierende Programmiersprache.
>>
>> Das stimmt ziemlich sicher nicht. Die Performance von
>> Tcl ist nicht so schlecht, wie häufig behauptet wird.
>>
>
> Die Performance von Tcl ist gegenüber einem optimierten
> C-Programm miserabel

Mein "nicht so schlecht, wie häufig behauptet wird"
bezog sich natürlich auf den Vergleich mit anderen
Scriptsprachen.

Der Vergleich "optimiertes C" gegen Scriptsprache ist
weitgehend sinnfrei.


> (nach meinen Versuchen nicht nur Faktor 2 oder so,
> sondern eher 200 bis 2000).

Und das liegt jetzt daran, dass Tcl kein "goto" kennt?
Ich sehe nicht, worauf Du hinauswillst.


>>> Tcl ist ein Plastiklöffel.
>>
>> Was soll das?
>
> Wenn Du meinen Beitrag oben gelesen hättest, würdest Du
> das verstehen.

Ich lese alle Beiträge -- und insonderheit die, auf die ich
antworte --, aber ich verstehe trotzdem nicht, was Du meinst.
Hilf mir auf die Sprünge.

Beitrag #5289766 wurde von einem Moderator gelöscht.
von 900ss (900ss)


Lesenswert?

Possetitjel schrieb:
> Jetzt musst Du nur noch die Labels verwechseln, und die
> ungewollte Schleife ist fertig.

Das ist ein Programmierfehler, den man dann behebt. Darum geht es aber 
doch garnicht hier. Programmierfehler kannst du mit jedem 
Sprachkonstrukt machen.

Possetitjel schrieb:
> Was ich wissen wollte: Welches Regelwerk ist es denn?

Hausintern, abgeleitet von Kundenanforderungen.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Da das hier nun bereits die x-te Diskussion zum Thema Goto ist (x≥10),
möchte ich einmal eine ganz banale Frage in den Raum stellen:

Wann habt ihr zum letzten Mal Quellcode in C, Pascal oder irgendeiner
anderen Programmiersprache mit strukturierenden Sprachelementen gesehen,
der Gotos in einer Art und Weise verwendet, die tatsächlich an die
berühmten italienischen Nudeln erinnert?

Bei mir ist das geschätzte 30 Jahre her. Damals und in den Jahren davor
wollten viele Leute vom Basic auf ihrem Heimcomuter (Commodore, Apple,
Atari und wie sie alle hießen) auf modernere Sprachen wie Pascal und C
umsteigen, wussten aber zunächst mit den neu hinzugekommenen Features
wie If-Then-Else, For-/While-Schleifen und Funktionen/Prozeduren mit
Argumentlisten nicht viel anzufangen. Entsprechend gruselig und Basic-
ähnlich sahen ihre Programme aus.

Die in der Folge stattfindende Brandmarkung des Goto an praktisch allen
(Hoch-)Schulen und sonstigen Lehrstätten hat ihre Wirkung aber nicht
verfehlt: Seit den 90er Jahren verwenden Anfänger das Goto praktisch
überhaupt nicht mehr, weil es ihnen genau so eingeprügelt wurde, und die
Fortgeschrittenen verwenden es nur selten und dann mehr oder weniger
begründet. Das ist zumindest meine Beobachtung.

Muss man also die Diskussion um das Für und Wider von Goto immer wieder
von Neuem beginnen, oder hat sich das Problem Wirklichkeit schon längst
erledigt?

Ich meine, letzteres ist der Fall.


Nop schrieb:
> Zudem haben 95.34% der Leute, die goto wegen Dijkstras legendärem "goto
> considered harmful"-Papers verreißen, den Aufsatz überhaupt nicht
> begriffen, sondern plappern nur nach, was sie irgendwo aufgeschnappt
> haben.

Die meisten wissen auch nicht, dass der reißerische Titel des Artikels
gar nicht von Dijkstra selbst, sondern von Wirth stammt (der ein paar
Jahre später witzigerweise das Goto in sein Pascal eingebaut hat :)).
Der ursprüngliche Titel lautete "A Case Against the Goto Statement".

von Einer K. (Gast)


Lesenswert?

Yalu X. schrieb:
> Wann habt ihr zum letzten Mal Quellcode in C, Pascal oder irgendeiner
> anderen Programmiersprache mit strukturierenden Sprachelementen gesehen,
> der Gotos in einer Art und Weise verwendet, die tatsächlich an die
> berühmten italienischen Nudeln erinnert?

Du meinst mich?
Dann: Noch NIE!

Damals in (uralt) Basic, ja.(aber das war ja nicht die Frage)
Aber danach nie wieder.

Und wenn ich mich frage, wie oft ich Goto einsetze, dann würde ich das 
auf durchschnittlich 1 bis 2 mal im Jahr schätzen.
Höchstens.

von Achim S. (Gast)


Lesenswert?

Yalu X. schrieb:
> Wann habt ihr zum letzten Mal Quellcode in C, Pascal oder irgendeiner
> anderen Programmiersprache mit strukturierenden Sprachelementen gesehen,
> der Gotos in einer Art und Weise verwendet, die tatsächlich an die
> berühmten italienischen Nudeln erinnert?

Ergänzend dazu hier ein Auszug aus dem C++ Style Guide von Google:
https://google.github.io/styleguide/cppguide.html

"Style rules should pull their weight
    The benefit of a style rule must be large enough to justify asking 
all of our engineers to remember it. The benefit is measured relative to 
the codebase we would get without the rule, so a rule against a very 
harmful practice may still have a small benefit if people are unlikely 
to do it anyway. This principle mostly explains the rules we don’t have, 
rather than the rules we do: for example, goto contravenes many of the 
following principles, but is already vanishingly rare, so the Style 
Guide doesn’t discuss it."

Die Nutzung von Goto wird darin also explizit nicht geregelt. Die 
Nutzung von Goto wird zwar durchaus als nicht unkritisch gesehen ("goto 
contravenes many of the following principles"). Aber gleichzeitig tritt 
es so selten in deren Code auf ("already vanishingly rare") dass es 
nicht Wert ist, sich dafür eine Regel merken zu müssen.

von Paul B. (paul_baumann)


Lesenswert?

Arduino F. schrieb:
> Und wenn ich mich frage, wie oft ich Goto einsetze, dann würde ich das
> auf durchschnittlich 1 bis 2 mal im Jahr schätzen.
> Höchstens.

Wieviele Programme schreibst Du denn im Jahr?
1-2 höchstens?
:)

MfG Paul

von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

Jörg W. schrieb:
> In anderen Sprachen mit Exceptions. ;-)
Wenn man Exceptions zur Verfuegung hat, dann geht das damit durchaus 
schoener, ja. Hat man in C aber nicht :o)


Torsten R. schrieb:
> ich versuche es aber trotzdem mal ;-)
Netter Versuch. Das malloc moeglicherweise fehlschlaegt wurde ja schon 
genannt. :-)


Torsten R. schrieb:
> Ja, dass macht das Original aber auch.
Nein. Es wird nur der Speicher freigegeben, der auch wirklich allokiert 
wurde. Deswegen muessen in meinem Beispiel die Pointer auch nicht mit 
NULL initialisiert werden. Entweder hat die Allokation funktioniert, 
dann zeigt der Pointer auf eine gueltige Adresse, oder es hat nicht 
Funktioniert, dann ist er NULL. Wobei das an der Stelle auch egal ist, 
da nur die Speicher freigegeben werden, bei denen die Allokation 
erfolgreich war.


Possetitjel schrieb:
> Das ist aber nur ein LAUFZEITNACHTEIL und hat nichts mit
> der Lesbarkeit zu tun.
Doch, das hat sehr wohl was mit der Les- und Wartbarkeit zu tun.
Beispiel:
1
int bar(void)
2
{
3
    uint8_t *mem_1;
4
    uint16_t *mem_2;
5
    uint32_t *mem_3;
6
7
8
    mem_1 = malloc(10);
9
    if (mem_1 == NULL) {
10
        return -1;
11
    }
12
13
    /*  do fancy stuff  */
14
15
    mem_2 = malloc(23 * sizeof(uint16_t));
16
    if (mem_2 == NULL) {
17
        free(mem_1);
18
19
        return -2;
20
    }
21
22
    /*  do fancy stuff  */
23
24
    mem_3 = malloc(47 * sizeof(uint32_t));
25
    if (mem_3 == NULL) {
26
        free(mem_2);
27
        free(mem_1);
28
29
        return -3;
30
    }
31
32
    /*  do fancy stuff  */
33
34
    free(mem_3);
35
    free(mem_2);
36
    free(mem_1);
37
38
    return 0;
39
}


Und jetzt kloppen wir da mal noch 2 Zeiger rein:
1
int bar(void)
2
{
3
    uint8_t *mem_1;
4
    uint16_t *mem_2;
5
    uint32_t *mem_3;
6
      ...    *mem_4;
7
      ...    *mem_5;
8
9
10
    mem_1 = malloc(10);
11
    if (mem_1 == NULL) {
12
        return -1;
13
    }
14
15
    /*  do fancy stuff  */
16
17
    mem_2 = malloc(23 * sizeof(uint16_t));
18
    if (mem_2 == NULL) {
19
        free(mem_1);
20
21
        return -2;
22
    }
23
24
    /*  do fancy stuff  */
25
26
    mem_3 = malloc(47 * sizeof(uint32_t));
27
    if (mem_3 == NULL) {
28
        free(mem_2);
29
        free(mem_1);
30
31
        return -3;
32
    }
33
34
    /*  do fancy stuff  */
35
36
    mem_4 = malloc(...);
37
    if (mem_4 == NULL) {
38
        free(mem_3);
39
        free(mem_2);
40
        free(mem_1);
41
42
        return -4;
43
    }
44
45
    /*  do fancy stuff  */
46
47
    mem_5 = malloc(...);
48
    if (mem_5 == NULL) {
49
        free(mem_4);
50
        free(mem_3);
51
        free(mem_2);
52
        free(mem_1);
53
54
        return -5;
55
    }
56
57
    /*  do fancy stuff  */
58
    
59
    
60
    free(mem_5);
61
    free(mem_4);
62
    free(mem_3);
63
    free(mem_2);
64
    free(mem_1);
65
66
    return 0;
67
}
15x free, mit goto waeren es nur 5x free. Das finde ich schon deutlich 
unleserlicher als mit goto und es enthaelt sehr viel doppelten Code.

Possetitjel schrieb:
> Das Freigeben des Speichers muss man natürlich umformulieren.
Und wie? Wenn eine allokation fehlschlaegt kann die Funktion nicht 
weiter machen. Also muss an jeder Stelle wo Speicher allokiert wird, 
alle vorherigen, bereits erfolgreich allokierten Speicher, wieder 
freigegeben werden. Da helfen auch Hilfsvariablen nichts. Das kannst du 
an der Stelle umgehen, wenn man aus den ganzen if eine haessliche 
if-else-Kette macht (siehe unten).

Ich gebe aber auch zu, dass das Beispiel anfaengt sehr stark zu hinken, 
je mehr Zeiger/malloc man da jetzt in dieser einen Funktion hat.

So, ein letztes, hinkendes Beispiel hab ich noch :P
1
int foobar(void)
2
{
3
    ... *mem_1 = NULL;
4
    ... *mem_2 = NULL;
5
    ... *mem_3 = NULL;
6
    ... *mem_4 = NULL;
7
    ... *mem_5 = NULL;
8
9
    ... ret_val = 0;
10
11
12
    mem_1 = malloc(...);
13
    if (mem_1 == NULL) {
14
        ret_val = -1;
15
    } else {
16
        /*  ...  */
17
18
        mem_2 = malloc(...);
19
        if (mem_2 == NULL) {
20
            ret_val = -2;
21
        } else {
22
            /*  ...  */
23
24
            mem_3 = malloc(...);
25
            if (mem_3 == NULL) {
26
                ret_val = -3;
27
            } else {
28
                /*  ...  */
29
30
                mem_4 = malloc(...);
31
                if (mem_4 == NULL) {
32
                    ret_val = -4;
33
                } else {
34
                    /*  ...  */
35
36
                    mem_5 = malloc(...);
37
                    if (mem_5 == NULL) {
38
                        ret_val = -5;
39
                    } else {
40
                        /*  ...  */
41
                    }
42
                }
43
            }
44
        }
45
    }
46
47
    free(mem_5);
48
    free(mem_4);
49
    free(mem_3);
50
    free(mem_2);
51
    free(mem_1);
52
53
    return ret_val;
54
}

Oder so:
1
int foobar(void)
2
{
3
    ...
4
                    mem_5 = malloc(...);
5
                    if (mem_5 == NULL) {
6
                        ret_val = -5;
7
                    } else {
8
                        /*  ...  */
9
10
                        free(mem_5);
11
                    }
12
13
                    free(mem_4);
14
                }
15
16
                free(mem_3);
17
            }
18
19
            free(mem_2);
20
        }
21
22
        free(mem_1);
23
    }
24
25
    return ret_val;
26
}
In dieser Variante brauchen die Pointer wieder nicht mit NULL 
initialisiert zu werden.

Schoen ist das aber alles nicht. In diesem, gar nicht mal so speziellen 
Beispiel (Stichwort: Treiberprogrammierung), ist goto fuer mich allen 
anderen Konstruken haushoch ueberlegen, was die Les- und Wartbarkeit, 
sowie die Laufzeit angeht.


Yalu X. schrieb:
> Die meisten wissen auch nicht, dass der reißerische Titel des Artikels
> gar nicht von Dijkstra selbst, sondern von Wirth stammt
Immer hin: Wikipedia weiss das. :)
https://de.wikipedia.org/wiki/Sprunganweisung#Umstrittene_Verwendung_von_GOTO
1
1968 sprach sich Edsger W. Dijkstra in seinem Aufsatz
2
"Go To Statement Considered Harmful" (der Titel geht
3
allerdings auf Niklaus Wirth zurück), für eine Abschaffung
4
des Goto-Befehls in allen höheren Programmiersprachen aus.
5
6
...
7
8
In der Praxis hat sich jedoch gezeigt, dass der Verzicht auf
9
Goto zwar möglich ist, jedoch in einigen Fällen zu sehr aufwändigen
10
Konstrukten führt. So hält Donald E. Knuth Goto für die optimale
11
Lösung einiger üblicher Programmierprobleme.

https://web.archive.org/web/20051128093253/http://kerneltrap.org/node/553/2131
1
I think goto's are fine, and they are often more readable than
2
large amounts of indentation.
3
...
4
Of course, in stupid languages like Pascal, where labels cannot be
5
descriptive, goto's can be bad. But that's not the fault of the goto,
6
that's the braindamage of the language designer.
7
8
    Linus

von Joachim B. (jar)


Lesenswert?

Kaj G. schrieb:
> mem_1 = malloc(10);
>     if (mem_1 == NULL) {
>         return -1;
>     }
>
>     /*  do fancy stuff  */

ist aber auch mit Seitenausgang was man meiden sollte, soweit war ich 
mit meinem Code auch schon, gefiel mir aber auch nicht.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Joachim B. schrieb:
> ist aber auch mit Seitenausgang was man meiden sollte

Das gibt schon wieder Potential für Diskussionen ;-)

Aber mich interessiert was anderes:

Nachdem ich obigem Link zu Wikipedia gefolgt bin, lese ich da folgendes:
> In Sprachen, welche Ausnahmenbehandlung erlauben, wird dagegen die
> Ein-Ausstiegspunkt-Regel als obsolet angesehen, da throw-Anweisungen die
> Argumentation hinter dieser Regel ad absurdum führen.

Erklärt mir mal jemand glaubhaft, wie man mit Exceptions lesbar ein 
break, next, last oder continue schreibt?

Ich dachte ja immer, Exceptions wären Exceptions, wie der name schon 
sagt...

von Possetitjel (Gast)


Lesenswert?

Yalu X. schrieb:

> Da das hier nun bereits die x-te Diskussion zum Thema
> Goto ist (x≥10),

Naja, Diskussionsforen sind halt wie Schulklassen: Jedes
Jahr schlagen wieder Blödmänner auf, die nicht wissen,
wieviel 1+1 ist.

In diesem Fall war (wieder einmal) ich dieser Blödmann.


> Wann habt ihr zum letzten Mal Quellcode in C, Pascal
> oder irgendeiner anderen Programmiersprache mit
> strukturierenden Sprachelementen gesehen, der Gotos in
> einer Art und Weise verwendet, die tatsächlich an die
> berühmten italienischen Nudeln erinnert?

Noch nie, soweit ich das übersehe.


> Bei mir ist das geschätzte 30 Jahre her. Damals und in
> den Jahren davor wollten viele Leute vom Basic auf ihrem
> Heimcomuter (Commodore, Apple, Atari und wie sie alle
> hießen) auf modernere Sprachen wie Pascal und C umsteigen,
> wussten aber zunächst mit den neu hinzugekommenen Features
> wie If-Then-Else, For-/While-Schleifen und
> Funktionen/Prozeduren mit Argumentlisten nicht viel
> anzufangen. Entsprechend gruselig und Basic- ähnlich sahen
> ihre Programme aus.

Hmm. Nach meinem Gefühl war (mangels einschlägiger Computer)
die BASIC-Welle im Osten nicht so hoch. Ich bin in der
zweiten Hälfte der 80er so großgeworden, dass man strukturiert
programmieren soll, wenn man es anständig machen will. Klar
ist das mit'm Assembler etwas schwierig, aber das sollte das
Ziel sein.


> Muss man also die Diskussion um das Für und Wider von
> Goto

Nein, das ist ein Missverständnis.

Ich brauche goto nicht und muss dessen Für und Wider daher
auch nicht diskutieren.

Ich wollte wissen, warum die C-Programmierer, die einerseits
zugeben, dass man goto nur relativ selten braucht, andererseits
VEHEMENT dagegen sind, es komplett zu verbieten.

Ich wollte keine technische, sondern eine psychologische Frage
klären.
Ich wollte etwas über C lernen, indem ich etwas über die
Mentalität des C-Programmierers lerne :)


> immer wieder von Neuem beginnen, oder hat sich das Problem
> Wirklichkeit schon längst erledigt?
>
> Ich meine, letzteres ist der Fall.

Jein: Das "ursprüngliche" Problem mit goto, auf das sich
der Dijkstra-Artikel bezieht, ist sicherlich schon lange
behoben.

Aber: Die Fragen nach goto, strukturierter Programmierung
und ähnlichem haben (auch) einen automatentheoretischen
Hintergrund, bei dem ich das diffuse Gefühl habe, er werde
sträflich vernachlässigt (weniger in der täglichen Programmier-
praxis, sondern primär in Lehre und Forschung). Im Beitrag
von Nop sind diese Dinge angeklungen.
Man kann Querverbindungen zur Steuerungsprogrammierung, zu
programmierbarer Logik, zu den aktuellen Sicherheitslücken
und schätzungsweise auch zur funktionalen Programmierung
ziehen.

> Die meisten wissen auch nicht, dass der reißerische Titel
> des Artikels gar nicht von Dijkstra selbst, sondern von
> Wirth stammt

Naja, das ist aus dem Pdf mit seinem Artikel nicht zu ersehen.


> (der ein paar Jahre später witzigerweise das Goto in sein
> Pascal eingebaut hat :)).

Ja! Schande über ihn!
Und "Hoch Ousterhout" dafür, dass er dieser Versuchung
widerstanden hat!

von Possetitjel (Gast)


Lesenswert?

Kaj G. schrieb:

> Possetitjel schrieb:
>> Das ist aber nur ein LAUFZEITNACHTEIL und hat nichts mit
>> der Lesbarkeit zu tun.
>
> Doch, das hat sehr wohl was mit der Les- und Wartbarkeit
> zu tun.

???
Ich verstehe Dein Beispiel nicht.

[...]
> So, ein letztes, hinkendes Beispiel hab ich noch :P

Ich stricke Dein Beispiel mal so um, wie ich es meine.
Ich hoffe, das Prinzip wird erkennbar, obwohl ich kein
C kann; Syntaxfehler sind wahrscheinlich.
1
 
2
int foobar(void)
3
{
4
    ... *mem_1 = NULL;
5
    ... *mem_2 = NULL;
6
    ... *mem_3 = NULL;
7
    ... *mem_4 = NULL;
8
    ... *mem_5 = NULL;
9
10
    ... ret_val = 0;
11
12
    mem_1 = malloc(...);
13
    if (mem_1 == NULL) {
14
        ret_val = -1;
15
    } else {
16
        /*  ...  */
17
    } 
18
19
    if (ret_val == 0) { 
20
      mem_2 = malloc(...);
21
      if (mem_2 == NULL) {
22
          ret_val = -2;
23
      } else {
24
        /*  ...  */
25
      } 
26
    } 
27
28
    if (ret_val == 0) { 
29
      mem_3 = malloc(...);
30
      if (mem_3 == NULL) {
31
          ret_val = -3;
32
      } else {
33
        /*  ...  */
34
      } 
35
    } 
36
37
    if (ret_val == 0) { 
38
      mem_4 = malloc(...);
39
      if (mem_4 == NULL) {
40
          ret_val = -4;
41
      } else {
42
        /*  ...  */
43
      } 
44
    } 
45
46
    if (ret_val == 0) { 
47
      mem_5 = malloc(...);
48
      if (mem_5 == NULL) {
49
          ret_val = -5;
50
      } else {
51
        /*  ...  */
52
      } 
53
    } 
54
55
56
    free(mem_5);
57
    free(mem_4);
58
    free(mem_3);
59
    free(mem_2);
60
    free(mem_1);
61
62
    return ret_val;
63
}

von Zu Peinlich (Gast)


Lesenswert?

Yalu X. schrieb:
> Wann habt ihr zum letzten Mal Quellcode in C, Pascal oder irgendeiner
> anderen Programmiersprache mit strukturierenden Sprachelementen gesehen,
> der Gotos in einer Art und Weise verwendet, die tatsächlich an die
> berühmten italienischen Nudeln erinnert?

Wir haben hier ein größeres Projekt, > 100kLoc. Und als dann 61508 (SIL, 
Funktionale Sicherheit) anlag, kam mein Chef: "Kollege X fiel auf, Du 
verwendest goto. Bring das bitte in Ordnung". Naja, das war ein 
modifiziertes printf aus der Stdlib, das halt im Orignal ein paar 
(sinnvolle) gotos hat. Nee, sag ich, dann war's OK.

Das Interessante: X's Leute liebten Gotos. Mit Sprung in Else-Zweige 
etc. An einem Tag haben sie 3 Dutzend Gotos formal durch 
for(;;)/Switch-Case/continue ersetzt. Gut, Umarbeitung wäre 
fehlerträchtig, aber hey, gotos durch noch was bescheuertes ersetzen ist 
ganz sicher nicht Dijkstras Sinne.

Jedenfalls bin ich jetzt offiziell der einzige Spaghettiprogrammierer 
;-)

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


Lesenswert?

Yalu X. schrieb:
> Wann habt ihr zum letzten Mal Quellcode in C, Pascal oder irgendeiner
> anderen Programmiersprache mit strukturierenden Sprachelementen gesehen,
> der Gotos in einer Art und Weise verwendet, die tatsächlich an die
> berühmten italienischen Nudeln erinnert?

Im FORTRAN-Praktikum an der Uni. :)

In der Tat mehr als 30 Jahre her.  Ich war froh, als wir auf dem
PDP11-Clone des Fachbereichs unseren Pascal-Compiler zum Laufen bekommen
hatten. Dann konnte ich FORTRAN endlich zu den Akten legen.

von Einer K. (Gast)


Lesenswert?

Michael R. schrieb:
> Joachim B. schrieb:
>> ist aber auch mit Seitenausgang was man meiden sollte
>
> Das gibt schon wieder Potential für Diskussionen ;-)

Die sind irgendwie mit Goto und #define vergleichbar.
(vermutlich kann man jedes Sprachmittel dort einsetzen)

Jeder vermiedene Seitenausstieg ist ein guter Seitenausstieg.
Jeder vermeidbare Seitenausstieg ist ein böser Seitenausstieg.

Und das wieder mit der bekannten Unschärfe:
Kein Eiertanz wegen eines, der Situation unangemessenen, Dogmas.

z.B. gerade in ISRs machen schnelle Ausstiege gerne Sinn

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


Lesenswert?

Arduino F. schrieb:
> z.B. gerade in ISRs machen schnelle Ausstiege gerne Sinn

Trugschluss.
1
   if (failed)
2
      return;
3
   blahblah();
4
}

ist ja keineswegs schneller als
1
   if (!failed)
2
   {
3
      blahblah();
4
   }
5
}

Es ist nur so, dass immer tiefer geschachtelte if-Anweisungen
irgendwann die Lesbarkeit arg beeinträchtigen.

von Christopher J. (christopher_j23)


Lesenswert?

Possetitjel schrieb:
> Man sollte "for" als Ausgeburt eines Sprachsadisten verbieten
> und nur "while" und "do-while" erlauben...

Bei Go (golang) gibt es nur noch "for" aber kein "while" und erst recht 
kein "do-while". Die Schöpfer der Sprache meinten, dass das 
übersichtlicher bzw. weniger verwirrend sei. "goto" haben sie allerdings 
nicht wegrationalisiert ;)

von p41145 (Gast)


Lesenswert?

Hier ein kleines Beispiel (aus meiner Erinnerung) für ein sinnvollen 
Seitenausstieg (oder auch nicht). Hier werden alle bytes von einem 
Ringbuffer gelesen. Ist der Ringbuffer leer gibt es ein -1 zurück und 
darauf der Ausstieg.
1
void commandHandler(void) 
2
{
3
  uint8_t command[80];
4
  uint8_t byte;
5
  static uint8_t index;
6
  do
7
  {  /*uart_get empty -> -1*/
8
    if (uart_get(&byte)) return; 
9
    command[index++] = byte;
10
  } while (byte != '\r');
11
  commandInterpeter(command);
12
  index = 0;  
13
}

Ich weiß jetzt nicht bei wem sich die Fußnägel aufrollen, aber ich finde 
hier das return sinnvoll.

von A. S. (Gast)


Lesenswert?

Christopher J. schrieb:
> aber kein "while"

Naja, for(;x;) benötigt auch nicht mehr Zeichen als das äquivalente 
while(x).

Zudem verstößt (in C) while(1) gegen die meisten Regeln, während for(;;) 
nicht nur explizit erlaubt ist, sondern sogar TEUREN Quelltext-Speicher 
spart.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

p41145 schrieb:
> {  /*uart_get empty -> -1*/
>     if (uart_get(&byte)) return;


Lies Dir mal den Kommentar durch. Wann wird nach dem Aufruf von uart_get 
die Funktion beendet?

Davon abgesehen ist das hässlich formatiert - das return sollte, damit 
es auffällt, definitiv in einer eigenen Zeile und nicht hinten an das 
if-Statement drangeklatscht werden.

Des weiteren ist das ein typischer Fall eines nicht abgefangenen Buffer 
Overflows; was geschieht, wenn die UART hier mehr als 80 Zeichen 
empfängt, aber keines davon ein '\r' ist?

von A. S. (Gast)


Lesenswert?

p41145 schrieb:
> do
>   {  /*uart_get empty -> -1*/
>     if (uart_get(&byte)) return;
>     command[index++] = byte;
>   } while (byte != '\r');
1
while(uart_get(&byte)==0 && byte !='r')
2
{
3
    command[index++] = byte;
4
}
finde ich jetzt auch nicht schlimmer.

Wobei ich nichts vom Verbot des frühen Ausstiegs halte. Standards, die 
das immer noch verbieten sind m.E. outdated.

: Bearbeitet durch Moderator
von Thosch (Gast)


Lesenswert?

Autsch!
Den wesentlichen Fehler in dieser Funktion hat noch niemand bemängelt:
Buffer Overflow!
Da muss unbedingt eine Überprüfung des index auf Gültigkeit rein.

von Thosch (Gast)


Lesenswert?

Und der Index ist im ersten Aufruf ebenfalls nicht initialisiert...

von A. S. (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Lies Dir mal den Kommentar durch. Wann wird nach dem Aufruf von uart_get
> die Funktion beendet?

na, wenn der Uart-Puffer leer ist. So wie es sein sollte, oder?

Rufus Τ. F. schrieb:
> Des weiteren ist das ein typischer Fall eines nicht abgefangenen Buffer
> Overflows;

Der Code scheint so runter geschrieben zu sein, das return würde eh 
alles zerstören.

von Thosch (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Des weiteren ist das ein typischer Fall eines nicht abgefangenen Buffer
> Overflows;

ok. Den Beitrag hatte ich übersehen...

von p41145 (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Lies Dir mal den Kommentar durch. Wann wird nach dem Aufruf von uart_get
> die Funktion beendet?

Meiner Meinung nach direkt nach der if-Abfrage, falls der Buffer leer 
ist. Bin da auf dem Holzweg, was daran verkehrt ist?! Bei dem Rest geb 
ich natürlich recht, allein command[] müsste static sein. War jetzt auch 
nur schnell runtergeschieben als Beispiel.


Achim S. schrieb:
> while(uart_get(&byte)==0 && byte !='r')
> {
>     command[index++] = byte;
> }
> finde ich jetzt auch nicht schlimmer.

danach müsste jedoch der anschließende Code auch mit "byte !='r'" 
abgefangen werden. Ja, auch das bläht den Code jetzt nicht unnötig auf, 
wobei ein direkter Ausstieg wohl etwas schneller ist.

Thosch schrieb:
> Und der Index ist im ersten Aufruf ebenfalls nicht initialisiert...

als static nicht unbedingt nötig

von A. S. (Gast)


Lesenswert?

p41145 schrieb:
> danach müsste jedoch der anschließende Code auch mit "byte !='r'"
> abgefangen werden.

oh, ja, mein Code ist völliger Quatsch. Sorry.

von Christopher J. (christopher_j23)


Lesenswert?

Achim S. schrieb:
> Zudem verstößt (in C) while(1) gegen die meisten Regeln, während for(;;)
> nicht nur explizit erlaubt ist, sondern sogar TEUREN Quelltext-Speicher
> spart.

Gibt es tatsächlich solche Regeln die while(1) verbieten aber for(;;) 
erlauben? Irgendwelchen MISRA-Guidelines würde ich das ja glatt zutrauen 
;)

von Einer K. (Gast)


Lesenswert?

Christopher J. schrieb:
> Gibt es tatsächlich solche Regeln die while(1) verbieten aber for(;;)
> erlauben?

Und selbst wenn...
1
// C++
2
const bool stromAusfall = false;
3
4
while(!stromAusfall)
5
{
6
  // tuwas
7
}

Dann ist die Welt doch wieder in Ordnung, oder?

von Nop (Gast)


Lesenswert?

Christopher J. schrieb:

> Gibt es tatsächlich solche Regeln die while(1) verbieten aber for(;;)
> erlauben? Irgendwelchen MISRA-Guidelines würde ich das ja glatt zutrauen
> ;)

Dem ist auch so, und das aus gutem Grund. Nicht nur, daß die for-Version 
die schon von K&R definierte Version ist, sondern man hat damit auch 
nicht das Problem, unabsichtlich eine while-Bedingung zu schreiben, die 
irrtümlich immer zu "wahr" auswertet.

von Joachim B. (jar)


Lesenswert?

Rufus Τ. F. schrieb:
> Des weiteren ist das ein typischer Fall eines nicht abgefangenen Buffer
> Overflows; was geschieht, wenn die UART hier mehr als 80 Zeichen
> empfängt, aber keines davon ein '\r' ist?

das waren meine Gedanken, aber da ich nicht so extrem sattelfest in C 
bin ist es gut das du es anmerkst!

von Joachim B. (jar)


Lesenswert?

Nop schrieb:
> Christopher J. schrieb:
>
>> Gibt es tatsächlich solche Regeln die while(1) verbieten aber for(;;)
>> erlauben? Irgendwelchen MISRA-Guidelines würde ich das ja glatt zutrauen
>> ;)
>
> Dem ist auch so, und das aus gutem Grund. Nicht nur, daß die for-Version
> die schon von K&R definierte Version ist, sondern man hat damit auch
> nicht das Problem, unabsichtlich eine while-Bedingung zu schreiben, die
> irrtümlich immer zu "wahr" auswertet.

aber normalerweise nutzt man while( a != b ) weil man was erreichen 
will, zum Testen setzt man es mal auf while(1), es bleibt while.

Nun zum Testen while(1) zu for(;;) zu ersetzen ist doch nicht weniger 
fehleranfällig, zumal wer der Code lesen und überarbeiten soll.

bei while ist es verständlich das aus Versehen die 1 drin steht,
bei for(;;) grübelt man ne Weile was wollte der Autor hier?

von Nop (Gast)


Lesenswert?

Joachim B. schrieb:

> aber normalerweise nutzt man while( a != b ) weil man was erreichen
> will

Nö, while-Bedingungen können auch etwas komplexer sein. Da kann sich 
dann schnell mal durch einen Tippfehler etwas einschleichen, was zu 
"always true" führt, und das sollen statische Analyser anmeckern.

> Nun zum Testen while(1) zu for(;;) zu ersetzen ist doch nicht weniger
> fehleranfällig

Zum Testen ist es ja auch egal, was man tut. Der Compiler frißt auch 
while(1), und für den Debug-Build kann man die Anmerkungen des Analysers 
ignorieren.

> bei for(;;) grübelt man ne Weile was wollte der Autor hier?

Da grübelt man gar nicht, das ist seit K&R-Zeiten einfach C. Wenn man da 
einen grübelnden Programmierer hat, ist das ein Fall von PEBKAC.

von Joachim B. (jar)


Lesenswert?

Nop schrieb:
> Da grübelt man gar nicht, das ist seit K&R-Zeiten einfach C.

du verstehst nicht, ich meinte als while Ersetzung

ich finde es halt doof statt der echten Bedingung
while( a != b )
zum Testen
while(1) gegen for(;;) zu ersetzen

aber du hast Recht lieber Gast und das musste mal gesagt werden

for(;;)
Nop schrieb:
> das ist seit K&R-Zeiten einfach C

gut das wir drüber geschrieben haben

Nop schrieb:
> while-Bedingungen können auch etwas komplexer sein

noch so eine schlaue Bemerkung, hast du noch ein paar?

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


Lesenswert?

Joachim B. schrieb:
> ich finde es halt doof statt der echten Bedingung while( a != b ) zum
> Testen while(1) gegen for(;;) zu ersetzen

Wenn du etwas zum Testen ersetzen willst, wird das keinen Menschen
interessieren.

Es geht doch lediglich darum, dass die Tools für statische Codeanalyse
ein "while (condition)" sauber anmosern können, wenn sie bemerken, dass
"condition" zur Compilezeit konstant "true" ist.  Sie gehen dann von
einem Programmiererfehler aus.

Bei "for (;;)" ist dagegen einfach klar, dass der Programmierer das
explizit so hingeschrieben hat.  Die Wahrscheinlichkeit, dass sich
dort ein Fehler einschleichen konnte, ist minimal; sie beschränkt sich
auf irgendwelche irrwitzigen Dinge wie:
1
  for (A; B; C)

bei denen A, B und C Makros sind, die zu nichts evaluieren.  Dass alle
drei Elemente eine for-Anweisungen aus Makros bestehen, ist mir aber
in freier Wildbahn noch nie über den Weg gelaufen.

von A. S. (Gast)


Lesenswert?

Joachim B. schrieb:
> for(;;)
> Nop schrieb:
>> das ist seit K&R-Zeiten einfach C
>
> gut das wir drüber geschrieben haben

Der Standard schreibt explizit, dass
1
for(a;b;c){code;}
und
1
a;while(b){code; c;}

äquivalent sind, dass a, und c entfallen können und das b als non-Zero 
gewertet wird, wenn es enfällt.

Der Knackpunkt ist nun, dass b nur bei for entfallen darf.

Man muss ja nicht alles kennen. Ich fände es nur schade, wenn jemand, 
der den offiziellen Weg nun kennt, am alten Heck festhalten würde.

von BeOS (Gast)


Lesenswert?

Arduino F. schrieb:
> while(!stromAusfall)

Da fällt mir was lustiges dazu ein, aus der BeOS API:
1
double is_computer_on_fire(void)

>Returns the temperature of the motherboard if the computer is currently on
>fire. If the computer isn't on fire, the function returns some other value.

von Druckertreiber (Gast)


Lesenswert?

Jörg W. schrieb:
> Es geht doch lediglich darum, dass die Tools für statische Codeanalyse
> ein "while (condition)" sauber anmosern können, wenn sie bemerken, dass
> "condition" zur Compilezeit konstant "true" ist.  Sie gehen dann von
> einem Programmiererfehler aus.
>
> Bei "for (;;)" ist dagegen einfach klar, [...]
Das ist doch ein Pseudoargument.
- Erstens koennte der Kompiler alle whiles die konstant true sind,  a u 
s s e r  while(1), anmosern.
- Zweitens kann es vom Programmierer gewollt sein, z.B.:
  #define Debugging = 1;

  while(InInitialisation or Debugging){}

von A. S. (Gast)


Lesenswert?

Druckertreiber schrieb:
> Das ist doch ein Pseudoargument.
> - Erstens koennte der Kompiler alle whiles die konstant true sind,  a u
> s s e r  while(1), anmosern.

Ja natürlich "könnte". Aber es gibt genau einen dafür im Standard 
vorgesehenen Mechanismus. Da ist es sinnlos, darüber zu diskutieren, 
dass man es auch anders machen könnte.

Genauso könnte man bei while auch die leere Klammer erlauben (wie bei 
for das leere mittlere Element). Hat man aber nicht, und darum ist 
while(1) genauso unsinnig wie for(;1;)

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.