Forum: Mikrocontroller und Digitale Elektronik goto verpönt - was dann nehmen?


von Walter S. (avatar)


Lesenswert?

hier Mal meine Version des obigen Codes (Tippfehler incl.)
das while (1) zeigt gut dass hier eine Endlosschleife droht

int portIsInList( PCB *pcb, PORT port )
{
  for( ; pcb != NULL; pcb = pcb->next)
    if (pcb->local_port == port)
      return true;

  return false;
}

 while ( 1 )
 {
   if (port++ >= TCP_LOCAL_PORT_RANGE_END) {
      port = TCP_LOCAL_PORT_RANGE_START;
    }

  /* Check all PCB lists. */
  for (i = 0; i < NUM_TCP_PCB_LISTS; i++)
    if ( portIsInList(*tcp_pcb_lists[i], port)
      break;

  if ( i == NUM_TCP_PCB_LISTS )
    return port;
  }

: Bearbeitet durch User
von MCUA (Gast)


Lesenswert?

>> wie schon geschrieben
>> Wenn bsp.weise in mehreren Else-Zweigen die Gleiche (Fehler oder
>> Sonstige)Behandlung durchgeführt werden soll.
>> Das geht Nicht ohne Umwege!
>Dann hat man einen Fehler bzw. eine Schwachstelle im Software-Design:
Oder dein Design ist zu billig.
Man kann nämlich nicht ausschliessen, dass im Programm mehrere 
Überprüfungen (betr. eines Sachverhalts) gemacht werden sollen, die im 
Nicht-Erfolgs-Falle in einer gemeinsamen Behandlung münden.

von Falk B. (falk)


Lesenswert?

@ Walter S. (avatar)

>mehr überblickt habe, muss ich leider sagen dass diese Umsetzung
>fehlerhaft ist:

>wenn die innerste Schleife mit
>pcb == NULL
>abbricht und dann zu
>if (pcb->local_port == port)
>kommt gibt es einen Fehler.

Hmm, stimmt.

> Richtig wäre stattdessen
>if ( pcb!=NULL )
>entsprechend beim while
>i < NUM_TCP_PCB_LISTS

Hmm.

>hier Mal meine Version des obigen Codes (Tippfehler incl.)
>das while (1) zeigt gut dass hier eine Endlosschleife droht

Auch die ist nicht korrekt ;-)
Und ich mag keine Schleifen mit nur einer Anweisung ohne Klammern.

>  if ( i == NUM_TCP_PCB_LISTS )
>    return port;
>  }

Und welchen Rückgabewert gibt es, wenn die Bedingung NICHT erfüllt ist?

Aber der Ansatz mit dem Zerlegen in Teilfunktionen ist deutlich besser! 
Genau SO macht man das!

Aber ich muß gestehen, daß ich den Sinn dieses Programmabschnitts noch 
nicht so ganz verstehe.
Es gibt ein Array pcb, welches Pointer auf verkettete Listen enthält 
(äußere Schleife). In der inneren Scheilfe wird nach einem Eintrag 
gesucht, welcher == port ist. Ist dieser gefunden, wird der port erhöht? 
Nur wenn alle verketteten Listen durchsucht wurden und KEIN port 
gefunden wurde, wird port zurückgegeben? Also ist die Funktion "Suche 
den Port, der NIRGENDWO enthalten ist"? Ich kenne den Gesamtzusammenhang 
hier nicht, aber ich denke, daß dort auch ein definiertes 
Abbruchkriterium fehlt, den im Extremfall wird das eine Endlosschleife, 
wenn JEDER mögliche Port immer gefunden wird, auch wenn das extrem 
selten ist.

Also besser so. Und siehe da, es ist genau so kompakt wie die 
goto-Variante und definitv OHNE Gefahr einer Endlosschleife! Es geht 
auch ohne Funktion zum Durchsuchern der verketteten Liste.

1
  int i = TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START;
2
  found = 1;
3
4
  for (; found && i>0; i--) {    
5
    if (port++ >= TCP_LOCAL_PORT_RANGE_END) {
6
      port = TCP_LOCAL_PORT_RANGE_START;
7
    }
8
    /* Check all PCB lists for port occurance */    
9
    for (i = 0, found = 0; !found && i < NUM_TCP_PCB_LISTS; i++) {
10
      for(pcb = *tcp_pcb_lists[i]; !found && pcb != NULL; pcb = pcb->next) {
11
        if (pcb->local_port == port) found = 1;
12
      }
13
    }
14
  }
15
16
  if (i==0) {
17
    // error, all ports are in lists
18
    return ERROR;
19
  } else {
20
    return port;    // port is not in lists
21
  }

Und jetzt werden die Goto-ianer wieder über die Hilfsvariable found 
lästern ;-)

: Bearbeitet durch User
von Zeno (Gast)


Lesenswert?

Daniel A. schrieb:
> Ich bin dafür, sofern es den Code vereinfacht, lesbarer macht und nicht
> zu oft verwendet wird.
> Falk Brunner ist dagegen, sofern es nicht sinvoll oder notwendig ist?
> Mark Brandis ist dagegen, wenn immer es ohne geht oder es von einem
> Anfänger benutzt wird?
> W.S. scheint für goto zu sein?
> Zeno sympathisiert mit W.S. ?
>
> Habe ich das so richtig im Kopf?

Alles korrekt in der Birne. Hatte in dem Post ja auch nicht Dich 
angesprochen. Sieh Dir doch nur an wie man sich zwischenzeitlich schon 
ein ein paar Zeilen Code aufgeilt. Langsam wird es peinlich.

Programmierer schrieb:
> Im Prinzip ist es einfach: Wer "goto" verteidigt und nicht missbilligt,
> muss noch ein paar Sprossen die Leiter der Erkenntnis nach oben
> klettern.
Glückwunsch! Du scheinst ganz oben auf der Leiter zu stehen. Aber 
Vorsicht noch ein Schritt, dann bist Du auch ganz schnell wieder unten.

nichtCler schrieb:
> Noch furchtbarer als meine Kommentare? Das macht mir Angst und stelle
> deshalb das Schreiben in diesem thread ein.

Ach Du darfst ruhig weiter schreiben. Wir machen doch alle Fehler - gilt 
auch bei Rechtschreibung.

M. K. schrieb:
> Durchs Knie ins Auge schießen kann man in C nicht nur mit goto, das geht
> mit allen Schleifen prima.
Geht in allen Programmiersprachen.

sepp schrieb:
> Wie du in deinem Beitrag selbst schon schreibst ist es wichtig gut
> strukturierte Software zu schreiben und du zeigst ja auch das man ohne
> goto einiges falsch machen kann. Goto kann falsch angewendet, schnell zu
> schlecht strukturierter Code führen aber in einigen Fällen auch sehr
> hilfreich sein um gut strukturierten Code zu erzeugen.
Richtig! Ist halt immer wieder schön wenn jemand heraus findet, das sich 
ein selbst ernannter Gott mal wieder klassisch ins Knie gebohrt hat.

Mark B. schrieb:
> Die bisherigen Beispiele sind kein Beweis, denn sie sind entweder
> unvollständig oder verstoßen gegen Best Practice-Regeln des Software
> Designs oder beides.

Da Du generell gegen die Verwendung von goto bist, wird sich kein Code 
mit goto finden lassen der Deinen sturen Ansichten genügt.


@MCUA, @blablablubb : Laßt es! Mark weiß es immer besser, es gilt nur 
seine Meinung. Das Beste wird wohl sein Burschen links liegen zu lassen.

Mikro 7. schrieb:
> In den Referenzen findet man dann auch u.a. Linus' Statement dazu:
>
> I think goto's are fine
Schau in den Folgepost und Du wirst sehen auch hierzu hat Mark ein 
Statement - er weis es natürlich besser. Aber jetzt scheinen ihm langsam 
die Argumente auszugehen und deshalb muß jetzt dies

Mark B. schrieb:
> Linus Torvalds hat nie ein Buch über Software-Design geschrieben. Oder
> über Software-Architektur. Oder darüber, wie man Software richtig
> testet.
herhalten. Linus T. ist ja auch nur so ein Dau der von nichts eine 
Ahnung hat.

Mark B. schrieb:
> Warum wohl? ;-)

Er ist ja der Vater des Linuxkerns und das ist BS und das ist ja nach 
Ansicht einige Leute hier auch was ganz anders.
Allerdings zeugt Linus's Äußerung zu Pascal und zu seinem Erfinder 
Niklaus Wirth auch nicht von guter Kinderstube. Niklaus Wirth war 
sicherlich nicht geistig unterbelichtet.

Zeno

von Daniel A. (daniel-a)


Lesenswert?

Falk B. schrieb:
> Also ist die Funktion "Suche
> den Port, der NIRGENDWO enthalten ist"?

Wenn man in TCP eine neue Verbindung zu einem anderen Host herstellen 
will, muss man zuerst ein noch nicht benutztes source/destination 
address pair suchen. Da dieser Code, sofern nicht jede destination 
address eigene tcp_pcb_lists hat, die destination addresse ignoriert, 
kann man das System Lahmlegen indem man es dazu bringt 2^16-1 
Verbindungen herzustellen, falls dies vom restlichen Code her überhaupt 
möglich ist.

Als Rückgabe wert im falle eines Fehlers wäre hier 0 geeignet, da dieser 
Port ansonsten nicht verwendet werden darf.

von Zeno (Gast)


Lesenswert?

Falk B. schrieb:
> Und jetzt werden die Goto-ianer wieder über die Hilfsvariable found
> lästern ;-)

Nö warum? Eine Hilfsvariable kann doch durchaus Sinn machen unabhängig 
von while, for, goto etc.

von Falk B. (falk)


Lesenswert?

War noch ein kleiner Fehler drin 8-0
So ist es richtig und LESBAR!!!
1
  int i = TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START;
2
  found = 1;
3
4
  for (; found && i>0; i--) {    
5
    if (port++ >= TCP_LOCAL_PORT_RANGE_END) {
6
      port = TCP_LOCAL_PORT_RANGE_START;
7
    }
8
    /* Check all PCB lists for port occurance */    
9
    for (i = 0, found = 0; !found && i < NUM_TCP_PCB_LISTS; i++) {
10
      for(pcb = *tcp_pcb_lists[i]; !found && pcb != NULL; pcb = pcb->next) {
11
        if (pcb->local_port == port) found = 1;
12
      }
13
    }
14
  }
15
16
  if (found) {    
17
    return 0;       // error, all ports are in lists
18
  } else {
19
    return port;    // port is not in lists
20
  }

von Zeno (Gast)


Lesenswert?

Falk B. schrieb:
> Aber ich muß gestehen, daß ich den Sinn dieses Programmabschnitts noch
> nicht so ganz verstehe.

Ich sagte doch, das ich das Beispiel willkürlich aus den Sourcen 
herausgegriffen habe. Irgendwie geht es in der Gesamtdatei um den TCP 
Stack. Aber wirklich kann ich das nicht beurteilen und würde es mir auch 
nicht anmaßen. Da hilft nur eins selbst die Quellen anschauen.

von Falk B. (falk)


Lesenswert?

@ Daniel Abrecht (daniel-a)

>kann man das System Lahmlegen indem man es dazu bringt 2^16-1
>Verbindungen herzustellen, falls dies vom restlichen Code her überhaupt
>möglich ist.

Diverse Sicherheitslecks und andere Bugs basieren auf so etwas.
Solider, bombenfester Code vermeidet sowas sicher.

von blablablubb (Gast)


Lesenswert?

Mark B. schrieb:
> Dann zeig mir eins. Ein Beispiel mit goto, wo man keine andere
> Unterteilung des Codes in Funktionen, kein anderes Software Design hätte
> wählen können, das besser gewesen wäre.

Das habe ich bewusst nicht getan und werde es auch nicht tun. Und das 
hat zwei Gründe:
- Es wurde schon oft genug getan.
- Du wirst dir eine "schönere" Lösung mit Hilfsvariablen und Splittung 
in Funktionen aus den Fingern saugen, die in Wirklichkeit nicht schöner 
ist, sondern nur dazu dient dir ein gutes Gefühl zu geben.

von Mark B. (markbrandis)


Lesenswert?

blablablubb schrieb:
> Mark B. schrieb:
>> Dann zeig mir eins. Ein Beispiel mit goto, wo man keine andere
>> Unterteilung des Codes in Funktionen, kein anderes Software Design hätte
>> wählen können, das besser gewesen wäre.
>
> Das habe ich bewusst nicht getan und werde es auch nicht tun. Und das
> hat zwei Gründe:
> - Es wurde schon oft genug getan.
> - Du wirst dir eine "schönere" Lösung mit Hilfsvariablen und Splittung
> in Funktionen aus den Fingern saugen, die in Wirklichkeit nicht schöner
> ist, sondern nur dazu dient dir ein gutes Gefühl zu geben.

Im Gegensatz zu Euch habe ich Argumente dafür genannt, warum es so 
besser ist wie ich es beschreibe.

Wen eine bessere Modularität und eine bessere Testbarkeit des Codes 
nicht überzeugen, der ist wohl von der Mentalität der "Nach mir die 
Sintflut" Programmierer. "Wozu Unit Tests? Mein Code funktioniert auch 
so!"

Kenne ich, habe ich schon diverse Kollegen gehabt die so arbeiten. Die 
meisten von ihnen sind zum Glück nicht mehr da. Qualität setzt sich 
irgendwann eben doch durch, bzw. Mangel an Qualität fliegt raus.

von blablablubb (Gast)


Lesenswert?

Mark B. schrieb:
> Im Gegensatz zu Euch habe ich Argumente dafür genannt, warum es so
> besser ist wie ich es beschreibe.

Die Argumente für goto sind älter als das Internet und wurden schon 
millionenfach genannt. Das braucht man nicht mehr zu wiederholen.

> Wen eine bessere Modularität und eine bessere Testbarkeit des Codes
> nicht überzeugen, der ist wohl von der Mentalität der "Nach mir die
> Sintflut" Programmierer. "Wozu Unit Tests? Mein Code funktioniert auch
> so!"

Es ist doch völlig absurd zu behaupten der Code würde irgendwie magisch 
besser testbar, wenn man kein goto verwendet.
Um es mit Linus' Worten zu sagen: Only a moron would believe that.

von Mark B. (markbrandis)


Lesenswert?

blablablubb schrieb:
> Es ist doch völlig absurd zu behaupten der Code würde irgendwie magisch
> besser testbar, wenn man kein goto verwendet.

Das hat auch keiner so behauptet. Lerne lesen und Zusammenhänge 
verstehen, dann komm wieder.

: Bearbeitet durch User
von blablablubb (Gast)


Lesenswert?

Mark B. schrieb:
> Das hat auch keiner so behauptet.

Doch das hast du. Zitat:

>Im Gegensatz zu Euch habe ich Argumente dafür genannt, warum es so
>besser ist wie ich es beschreibe.
>Wen eine bessere Modularität und eine bessere Testbarkeit des Codes
>nicht überzeugen, der ist wohl von der Mentalität der "Nach mir die
>Sintflut" Programmierer.

Und jetzt höre auf zu lügen.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Noch einmal zu dem von Zeno geposteten Beispielcode aus lwIP:

Ein Rückwärts-Goto ist böser als ein Vorwärts-Goto, da er eine Schleife
kaschiert. Für Schleifen stellt C aber genügend Konstrukte zur Auswahl
(for, while, do), von denen praktisch immer eines passend ist.

Und die Prüfung, ob der jeweils betrachtete Port schon benutzt wird,
schreit gerade danach, in eine eigene Funktion ausgelagert zu werden.

Deswegen sähe mein Vorschlag so aus:

1
static bool port_is_in_use(u16_t port) {
2
  struct tcp_pcb *pcb;
3
  int i;
4
5
  for (i = 0; i < NUM_TCP_PCB_LISTS; i++) {
6
    for(pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) {
7
      if (pcb->local_port == port)
8
        return true;
9
    }
10
  }
11
  return false;
12
}
13
14
static u16_t tcp_new_port(void) {
15
  static u16_t port = TCP_LOCAL_PORT_RANGE_START;
16
17
  do {
18
    if (port++ >= TCP_LOCAL_PORT_RANGE_END)
19
      port = TCP_LOCAL_PORT_RANGE_START;
20
  } while(port_is_in_use(port));
21
22
  return port;
23
}

Die Funktion port_is_in_use enthält zwar immer noch einen verkappten
Goto, nämlich die Return-Anweisung inmitten der inneren Schleife. Zum
einen ist das aber ein Vorwärtssprung, der nicht ganz so böse ist, zum
anderen ist die Funktion so kurz, dass trotz dieses Schönheitsfehlers
ihre Ablaufstruktur mit einem Blick erfasst werden kann.

Man könnte natürlich die innere Schleife in eine weitere Funktion
auslagern und käme dann mit jeweils einem Break als Schleifenabbruch
aus. Bei dieser kurzen Funktion halte ich es aber für übertrieben, sie
weiter aufzuteilen.

Welche der drei Versionen (Original, von Falk und die obige) am besten
lesbar ist, muss jeder subjektiv für sich entscheiden.

Effizienz ist in diesem Fall übrigens kein Argument für den Goto im
Originalcode, denn der GCC erzeugt aus dem obigen Quelltext
erwartungsgemäß den gleichen Assemblercode.

Hier ist der Vollständigkeit halber noch der Kommentar über dem
Originalcode dieser Funktion:

1
/*
2
 * tcp_new_port():
3
 *
4
 * A nastly hack featuring 'goto' statements that allocates a
5
 * new TCP local port.
6
 */

;-)

von Zeno (Gast)


Lesenswert?

Mark B. schrieb:
> Wen eine bessere Modularität und eine bessere Testbarkeit des Codes
> nicht überzeugen, der ist wohl von der Mentalität der "Nach mir die
> Sintflut" Programmierer. "Wozu Unit Tests? Mein Code funktioniert auch
> so!"
>
> Kenne ich, habe ich schon diverse Kollegen gehabt die so arbeiten. Die
> meisten von ihnen sind zum Glück nicht mehr da. Qualität setzt sich
> irgendwann eben doch durch, bzw. Mangel an Qualität fliegt raus.

Unit Tests ist kein Garant für fehlerfreien Code, denn den Testfall 
generiert der Programmierer und wenn der einen Fehler in seinem 
Denkansatz hat, dann geht es halt in die Hose.

von Daniel A. (daniel-a)


Lesenswert?

Zeno schrieb:
> Unit Tests ist kein Garant für fehlerfreien Code

Nicht unbedingt. Es ist häufig unrealistisch jeden möglichen Ausgabewert 
zu jedem möglichen Eingabewert zu überprüfen. Es kann durchaus 
passieren, dass ein Fehler bei einem Spezialfall enthalten ist, den man 
beim Testcase nict bedacht hatte oder nicht wissen konnte.

von Zeno (Gast)


Lesenswert?

Yalu X. schrieb:
> Welche der drei Versionen (Original, von Falk und die obige) am besten
> lesbar ist, muss jeder subjektiv für sich entscheiden.
Genau so ist es.
>
> Effizienz ist in diesem Fall übrigens kein Argument für den Goto im
> Originalcode, denn der GCC erzeugt aus dem obigen Quelltext
> erwartungsgemäß den gleichen Assemblercode.
Das vermag ich nicht zu beurteilen.
>
> Hier ist der Vollständigkeit halber noch der Kommentar über dem
> Originalcode dieser Funktion:
Endlich mal einer der nicht stur irgend etwas behauptet, sondern sich 
die Mühe macht mal die Quellen des Codeschnipsels anzusehen und erst 
dann sein Statement abgibt.


Zeno

von Zeno (Gast)


Lesenswert?

Daniel A. schrieb:
> Es ist häufig unrealistisch jeden möglichen Ausgabewert
> zu jedem möglichen Eingabewert zu überprüfen. Es kann durchaus
> passieren, dass ein Fehler bei einem Spezialfall enthalten ist, den man
> beim Testcase nict bedacht hatte oder nicht wissen konnte.

Genau das habe ich doch geschrieben - halt anders formuliert.

von Daniel A. (daniel-a)


Lesenswert?

Heute scheint irgendwie nicht mein Tag zu sein...

von Walter S. (avatar)


Lesenswert?

Falk B. schrieb:
> War noch ein kleiner Fehler drin 8-0
> So ist es richtig

fast ;-)
i wird doppelt verwendet

von blablablubb (Gast)


Lesenswert?

Walter S. schrieb:
> Falk B. schrieb:
>> War noch ein kleiner Fehler drin 8-0
>> So ist es richtig
>
> fast ;-)
> i wird doppelt verwendet

Ist ja voll einfach, übersichtlich und elegant, so ein Quellcode ohne 
goto.

von Mark B. (markbrandis)


Lesenswert?

blablablubb schrieb:
> Mark B. schrieb:
>> Das hat auch keiner so behauptet.
>
> Doch das hast du. Zitat:
>
>>Im Gegensatz zu Euch habe ich Argumente dafür genannt, warum es so
>>besser ist wie ich es beschreibe.
>>Wen eine bessere Modularität und eine bessere Testbarkeit des Codes
>>nicht überzeugen, der ist wohl von der Mentalität der "Nach mir die
>>Sintflut" Programmierer.
>
> Und jetzt höre auf zu lügen.

Erzähl doch keinen Käs.

Ich habe mehrere Male in diesem Thread gesagt, dass es in der Regel ein 
schlechtes Software-Design ist, das zur Verwendung von goto führt. Wenn 
man zu viel Code in eine einzelne Funktion hineinpackt, à la:
-Öffnen einer oder mehrer Ressource(n)
-Lesen von einer, oder Schreiben auf eine Ressource
-Behandlung von Fehlerfällen
-Schließen der Ressource(n)

dann kommt man leicht zu stark verschachteltem Code, wo man vielleicht 
dann gerne mal dazu geneigt ist, mit goto "auszubrechen". Man muss das 
Ganze aber nicht so aufziehen. Ein Refactoring führt zu besserem Code, 
der stärker modularisiert ist. In einem solchen Code wird goto zu 
99,999% überflüssig sein.

Natürlich steht es Dir frei, solche Argumente einfachb zu ignorieren, 
wie Du es ja auch tust. Dann ist eine Diskussion freilich sinnlos.

von Mark B. (markbrandis)


Lesenswert?

Zeno schrieb:
> Unit Tests ist kein Garant für fehlerfreien Code

Das ist schon richtig. Aber das hat auch niemand behauptet, dass dies 
ein Garant wäre. Und deswegen...

> denn den Testfall
> generiert der Programmierer und wenn der einen Fehler in seinem
> Denkansatz hat, dann geht es halt in die Hose.

...gibt es nach dem Unit Test noch einen Integrationstest und/oder 
entsprechend Regressionstests, die von jemand anderem als dem Entwickler 
durchgeführt werden.

So üblich in der Medizintechnik, im Automotive-Bereich, Luft- und 
Raumfahrt, Automatisierungstechnik, Schienenverkehrstechnik, 
Analytischen Messtechnik, ...

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

@Yalu X. (yalu) (Moderator)

>Und die Prüfung, ob der jeweils betrachtete Port schon benutzt wird,
>schreit gerade danach, in eine eigene Funktion ausgelagert zu werden.

Eben.

>Deswegen sähe mein Vorschlag so aus:

>static bool port_is_in_use(u16_t port) {

Ist OK.

>static u16_t tcp_new_port(void) {
>  static u16_t port = TCP_LOCAL_PORT_RANGE_START;

>  do {
>    if (port++ >= TCP_LOCAL_PORT_RANGE_END)
>      port = TCP_LOCAL_PORT_RANGE_START;
>  } while(port_is_in_use(port));

>  return port;
>}

Das hat wieder das Zeug zur Endlosschleife.

>/*
> * tcp_new_port():
> *
> * A nastly hack featuring 'goto' statements that allocates a
> * new TCP local port.
> */

ERWISCHT!

;-)

von blablablubb (Gast)


Lesenswert?

Mark B. schrieb:
> Erzähl doch keinen Käs.
>
> Ich habe mehrere Male in diesem Thread gesagt,
>blabla

Das bestreite ich alles nicht. UND du hast gesagt, dass der Code besser 
testbar ist, wenn kein goto verwendet wird. Und nur auf diese Aussage 
bezog ich mich. Sie ist halt Unsinn.

von Mark B. (markbrandis)


Lesenswert?

Yalu X. schrieb:
> Und die Prüfung, ob der jeweils betrachtete Port schon benutzt wird,
> schreit gerade danach, in eine eigene Funktion ausgelagert zu werden.

@blablablubb

Da hast Du's. Wenn Du mir schon nicht glauben willst, dann glaub 
wenigstens Yalu.

von blablablubb (Gast)


Lesenswert?

Mark B. schrieb:
> ...gibt es nach dem Unit Test noch einen Integrationstest und/oder
> entsprechend Regressionstests,
>...

Und was hat das alles mit dem Thema zu tun?
Es geht hier um goto.

von blablablubb (Gast)


Lesenswert?

Mark B. schrieb:
> Da hast Du's. Wenn Du mir schon nicht glauben willst, dann glaub
> wenigstens Yalu.

Der Missbrauch von goto als Schleifenkonstrukt ist nicht schön. Das habe 
ich nie bestritten.
Aber es gibt viele legitime Einsatzgebiete für goto. Diese wurden alle 
schon genannt und sind trivial auffindbar.

von Mark B. (markbrandis)


Lesenswert?

blablablubb schrieb:
> Das bestreite ich alles nicht. UND du hast gesagt, dass der Code besser
> testbar ist, wenn kein goto verwendet wird.

Nein. Du verstehst "Ursache und Wirkung" nicht, kann das sein?

1.) Ursache: Schlechtes SW-Design - zu viel Code/zu viel Funktionalität 
in einer Funktion

2.) Wirkung: Je nach Programmierer --> Unnötige Verwendung von goto, 
oder anderweitig miese Code-Qualität

3.) Heilung: Besseres SW-Design --> Kleinere Funktionen, Weniger stark 
verschachtelter Code, goto wird unnötig (falls es je nötig war ;-)

4.) Nebeneffekt: Kleinere Funktionen sind besser für Unit Tests.

Es ist nicht so schwer zu verstehen - wenn man mal drüber nachdenken 
mag.

: Bearbeitet durch User
von Mark B. (markbrandis)


Lesenswert?

blablablubb schrieb:
> Aber es gibt viele legitime Einsatzgebiete für goto. Diese wurden alle
> schon genannt und sind trivial auffindbar.

Mit "viele" meinst Du sicher:
-Kernel Hacking unter Linux
-Kernel Hacking unter OpenBSD
-Kernel Hacking unter FreeBSD
-Kernel Hacking unter NetBSD
-Kernel Hacking unter blablablubb OS

;-)

von blablablubb (Gast)


Lesenswert?

Mark B. schrieb:
> 1.) Ursache: zu viel Code/zu viel Funktionalität in einer Funktion
> 2.) Wirkung: Unnötige Verwendung von goto,

Das ist doch an den Haaren herbeigezogener Mumpitz. Es besteht doch kein 
Zusammenhang zwischen der Funktionalitätsmenge und goto. Schon gar nicht 
in dem Sinne, dass viel Funktionalität ein goto bedingt, was du ja 
implizierst.

von blablablubb (Gast)


Lesenswert?

Mark B. schrieb:
> Mit "viele" meinst Du sicher:
>...

Ja, unter anderem. Endlich hast du mal ein paar der immer wieder 
vorgetragenen Beispiele gefunden. Bravo.

von Mark B. (markbrandis)


Lesenswert?

blablablubb schrieb:
> Mark B. schrieb:
>> 1.) Ursache: zu viel Code/zu viel Funktionalität in einer Funktion
>> 2.) Wirkung: Unnötige Verwendung von goto,
>
> Das ist doch an den Haaren herbeigezogener Mumpitz. Es besteht doch kein
> Zusammenhang zwischen der Funktionalitätsmenge und goto.

Der Zusammenhang besteht zum Beispiel über die Verschachtelungstiefe, 
aus der mancher Programmierer (ich nicht) gerne mit goto "ausbricht".

von Zeno (Gast)


Lesenswert?

Mark B. schrieb:
> Dann ist eine Diskussion freilich sinnlos.

Mal an die eigene Nase fassen.

von blablablubb (Gast)


Lesenswert?

Mark B. schrieb:
> aus der mancher Programmierer (ich nicht) gerne mit goto "ausbricht".

Ja, das ist doch aber kein Muss.
Nur weil einige das machen, muss man doch goto nicht verteufeln.

von Falk B. (falk)


Lesenswert?

Der Ansatz von Yalu ist gut, die endgültige Funktion aber unsicher :-(
Besser so. Das ist wasserdicht, auch wenn man eher selten 64k Ports 
benutzen wird. Das ist so ähnlich wie die seltenen, nicht atomaren 
Zugriffsfehler auf ISR Variablen . . .
1
static u16_t tcp_new_port(void) {
2
  static u16_t port = TCP_LOCAL_PORT_RANGE_START;
3
  u16_t i;
4
5
  for (i=0xFFFF; i>0; i--) {
6
    if (port++ >= TCP_LOCAL_PORT_RANGE_END) {
7
      port = TCP_LOCAL_PORT_RANGE_START;
8
    }
9
    if (!port_is_in_use(port)) break;
10
  }
11
12
  if (i==0) {
13
    return 0;       // error, no more free ports
14
  } else {
15
    return port;
16
  }
17
}

von Zeno (Gast)


Lesenswert?

Mark B. schrieb:
> ...gibt es nach dem Unit Test noch einen Integrationstest und/oder
> entsprechend Regressionstests, die von jemand anderem als dem Entwickler
> durchgeführt werden.

Wie viele Tests hättest Du denn gern. Es wird keinen 100% fehlerfreien 
Code geben, das müssen wir nun halt mal akzeptieren.
Ohne jetzt hier noch einen Streit über die Qualität von 
Programmiersprachen vom Zaune brechen zu wollen behaupte ich jetzt mal, 
das die Qualität des Codes und/oder die Fehlerhäufigkeit schon davon 
abhängig ist, was der jeweilige Compiler / Interpreter an Schweinereien 
im Code zuläßt.

Und da kannst Du Testszenarien ohne Ende machen, wenn ein ein spezieller 
Fall nicht bedacht wird, wird es krachen wenn er denn eintritt.
Ich hab jetzt auch so einen Fall wo ein ganz Schlauer meint mit C# und 
Unit Test wird alles gut. Denkste! Mit 2 Klicks bringe ich das Programm 
zum Absturz und zwar so das es nicht mehr startbar ist und neu 
installiert werden muß.

Zeno

von blablablubb (Gast)


Lesenswert?

Falk B. schrieb:
> u16_t i;
>
>   for (...; i>0; ...) {

Ach bitte...

von Daniel A. (daniel-a)


Lesenswert?

blablablubb schrieb:
> Falk B. schrieb:
>> u16_t i;
>>
>>   for (...; i>0; ...) {
>
> Ach bitte...

Wie würdest du es schreiben? Ich würde vermutlich sowas machen:
1
u16_t i;
2
for( i=0; --i; ) {
3
...

von blablablubb (Gast)


Lesenswert?

Daniel A. schrieb:
> u16_t i;
> for( i=0; --i; ) {

Ach du lieeebe Zeit.

Rückwärtszählende Schleifen.
Schleifen, die Überlauf ausnutzen.

Das kommt dabei raus, wenn man krampfhaft versucht goto oder 
early-return zu vermeiden.
Warum nicht einfach ganz trivial vorwärts zählen und bei 
Abbruchbedingung die Funktion sofort mit early-return verlassen? Das 
wäre vermutlich zu einfach.

von Zeno (Gast)


Lesenswert?

Falk B. schrieb:
> for (i=0xFFFF;

ÄÄÄÄH waren magic Number nich schlechter Programmierstil - hat mir in 
diesem Thread gesagt.

Zeno

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Hallo,

ich würde dem bereits praktizierten Logikfehler „bei Praktikern schauen” 
gern ganz kurz noch ein weiteres Kapitel anfügen.

Gotos getestet mit grep -R "goto \\w\\+;" * | wc -l
und kurzer Sichtkontrolle ohne wc:

apache-httpd             265
git                      760
gnu scientific library    69
mysql server            7215
postgreSQL              2542
glibc                   2070

mehr großer und etablierter c-Code fiel mir so schnell nicht ein. 
Wahnsinn, dieses krasse Stümpertum überall.

vlg
 Timm

von Herbert P. (Gast)


Lesenswert?

rhf schrieb:
> Herbert P. schrieb:
>
>> Nicht zuletzt deshalb gilt diese Regel auch in meinen Vorlesungen
>> und Übungen, obwohl sie meine Studierenden auch immer wieder gerne
>> wegdiskutieren wollen...
>
> Was habe ich diese auf Formalien herum reitenden Professoren während
> meines Studiums gehasst. Meistens waren das auch genau die, bei denen
> ich am wenigsten gelernt habe, da sie aus ihrer fachlichen "Ecke" nicht
> heraus kamen. Aber egal.

Nun ja, Ansichtssache. Ich sehe das nicht als Formalie. Über die Jahre 
habe ich Pascal, Fortran, Prolog, Assembler, PL/I, C und andere 
praktisch in der Industrie verwendet. Mit und ohne goto, und ich habe 
meine Lektion gelernt. Ich finde aber, das es nicht notwendig ist, dass 
meine Studis alle meine Fehler wiederholen müssen. Die meisten verstehen 
es, und ein paar wenige brauchen halt etwas Nachdruck.

> Ich hätte aber einen Vorschlag für dich: Wenn du so davon überzeugt bist
> das die Verwendung von goto absolut abzulehnen ist, lasse doch von
> deinen Studenten einfach mal ein nicht triviales Programm schreiben in
> dem ausschließlich goto erlaubt ist. Ich finde mit einen solchen
> Beispiel könnte man doch sicherlich sehr anschaulich zeigen was für oder
> gegen die Verwendung von goto spricht.
>
>
Das ist gar keine dumme Idee. Ich danke dir für diese Anregung. Das 
werde ich wirklich mal ausprobieren. Bin gespannt, was dabei 
herauskommt. :D

Herby

von Mark B. (markbrandis)


Lesenswert?

Timm R. schrieb:
> apache-httpd             265
> git                      760
> gnu scientific library    69
> mysql server            7215
> postgreSQL              2542
> glibc                   2070
>
> mehr großer und etablierter c-Code fiel mir so schnell nicht ein.
> Wahnsinn, dieses krasse Stümpertum überall.

Nochmal für alle, die es immer noch nicht verstanden haben:

Quantität bezeugt keine Qualität.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Falk B. schrieb:
> Der Ansatz von Yalu ist gut, die endgültige Funktion aber unsicher :-(

Mir ging es nicht darum, Fehler in dem Code zu korrigieren, sondern zu
zeigen, wie man das Goto eliminieren kann, ohne dabei am Verhalten der
und der Effizienz der Funktion etwas zu ändern.

Natürlich hast du recht, die Funktion läuft in eine Endlosschleife, wenn
alle Ports belegt sind. Der Fehler ist im Original auch längst behoben:

  http://git.savannah.gnu.org/cgit/lwip.git/commit/src/core/tcp.c?id=112158b056c7b55498537cdb60e106b8075f465d

Witzigerweise wurde im gleichen Aufwasch auch der Kommentar mit dem
"nastly hack featuring 'goto' statements" entfernt, die Goto-Anweisung
selber wurde aber beibehalten :)

> for (i=0xFFFF; i>0; i--) {
>     if (port++ >= TCP_LOCAL_PORT_RANGE_END) {
>       port = TCP_LOCAL_PORT_RANGE_START;
>     }
>     if (!port_is_in_use(port)) break;
>   }

Das stimmt so nicht, denn es werden nicht alle 65535 Ports, sondern nur
diejenigen im Bereich von TCP_LOCAL_PORT_RANGE_START bis einschließlich
TCP_LOCAL_PORT_RANGE_END verwendet.

von Mark B. (markbrandis)


Lesenswert?

Yalu X. schrieb:
> Witzigerweise wurde im gleichen Aufwasch auch der Kommentar mit dem
> "nastly hack featuring 'goto' statements" entfernt, die Goto-Anweisung
> selber wurde aber beibehalten :)

Im Grunde genommen ist das nur halt leider nicht witzig, sondern ein 
Armutszeugnis.

Ich bin überzeugt davon, dass viele der von Timm Reinisch gelisteten 
Vorkommen von goto von einer ähnlich "guten" Qualität sind.

Es zeigt sich leider immer wieder: Auf Codequalität achtet so gut wie 
kein Schwein. :-(

von Tommi (Gast)


Lesenswert?

Um wirklich nicht mehr in die Goto-Versuchung zu kommen, würde ich mir 
ein solches Sprachmittel wünschen (in Pseudocode):
1
Procedure Foo()
2
3
  if xy then EXIT
4
5
POSTEXIT
6
  Cleanup...
7
End Procedure

D.h. dass man einen Bereich am Ende der Funktion/Routine definieren 
kann, welcher bei einem Exit aus der Funktion raus noch abgearbeitet 
wird. Das hielte ich auch für sauberen Code, da klar ist, wohin 
gesprungen wird.

von Falk B. (falk)


Lesenswert?

Schaff ich das noch heute noch?
1
static u16_t tcp_new_port(void) {
2
  static u16_t port = TCP_LOCAL_PORT_RANGE_START;
3
  u16_t i = TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START;
4
5
  for (; i>0; i--) {
6
    if (port++ >= TCP_LOCAL_PORT_RANGE_END) {
7
      port = TCP_LOCAL_PORT_RANGE_START;
8
    }
9
    if (!port_is_in_use(port)) break;
10
  }
11
12
  if (i==0) {
13
    return 0;       // error, no more free ports
14
  } else {
15
    return port;
16
  }
17
}

von blablablubb (Gast)


Lesenswert?

Mark B. schrieb:
> Nochmal für alle, die es immer noch nicht verstanden haben:
>
> Quantität bezeugt keine Qualität.

Du behauptest also ernsthaft, dass folgende Projekte qualitativ 
minderwertig sind?

> apache-httpd             265
> git                      760
> gnu scientific library    69
> mysql server            7215
> postgreSQL              2542
> glibc                   2070

Ich würde es stark bezweifeln.

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Hi,

Zeno schrieb im Beitrag #4547438:
> Mark B. schrieb:
>>> Wahnsinn, dieses krasse Stümpertum überall.
>>
>> Nochmal für alle, die es immer noch nicht verstanden haben:
>>
>> Quantität bezeugt keine Qualität.
>
> Dieses Statement war doch klar - alles Stümper.
> @Timm: Hast Du etwa was anderes erwartet?

Die Quantität der Fehler und Missverständnisse beim auf-teufel-komm-raus 
Ausmerzen des einen Goto belegt eigentlich alles :-)

vlg

 Timm

von Zeno (Gast)


Lesenswert?

Tommi schrieb:
> D.h. dass man einen Bereich am Ende der Funktion/Routine definieren
> kann, welcher bei einem Exit aus der Funktion raus noch abgearbeitet
> wird. Das hielte ich auch für sauberen Code, da klar ist, wohin
> gesprungen wird.

Das gibt es doch schon, z.B. bei Objektpascal.
1
try 
2
  ....
3
finally
4
  ....
5
end;

Man schreibt den kompletten Code für die Funktion zwischen try und 
finally und das was man immer machen möchte, also unbedingt ausführen 
möchte unabhängig davon ob während der Abarbeitung des Codes zw. try und 
finally ein Fehler passiert oder nicht, kommt zw. finally und end. Der 
Code zw. finally und end wird immer ausgeführt. Der im Codeteil der 
Funktion evtl. gebildete Returnwert wird natürlich an die aufrufende 
Funktion zurückgegeben, man kann ihn aber auch noch im finally/end-Block 
ändern, was z.B. bei einem Fehler Sinn macht.

Zeno

von blablablubb (Gast)


Lesenswert?

Tommi schrieb:
> D.h. dass man einen Bereich am Ende der Funktion/Routine definieren
> kann, welcher bei einem Exit aus der Funktion raus noch abgearbeitet
> wird.

Viele Sprachen mit Exceptions bieten dies. In Python heißt es "finally" 
bzw. der Exception-Handler selbst. Und in Sprachen, die das nicht 
bieten, kann mal es halt sehr schön mit goto machen. Da spricht absolut 
nichts dagegen.

> Das hielte ich auch für sauberen Code, da klar ist, wohin
> gesprungen wird.

Bei goto ist nicht klar wohin gesprungen wird??

von blablablubb (Gast)


Lesenswert?

Falk B. schrieb:
> Schaff ich das noch heute noch?
>   u16_t i = TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START;
>
>   for (; i>0; i--) {

Ich gehe mal davon aus, dass END und START der jeweils letzte und erste 
gültige Port sind.
Dann zählt es eins zu wenig.

Also.

> Schaff ich das noch heute noch?

Viel Glück :)

von blablablubb (Gast)


Lesenswert?

Zeno schrieb:
> und das was man immer machen möchte, also unbedingt ausführen
> möchte unabhängig davon ob während der Abarbeitung des Codes zw. try und
> finally ein Fehler passiert oder nicht, kommt zw. finally und end. Der
> Code zw. finally und end wird immer ausgeführt.

Das ist allerdings kein Ersatz für einen per goto gebauten 
fall-through-error-handler. (siehe Linux Kernel für Beispiele).

von Tommi (Gast)


Lesenswert?

Zeno schrieb:
> Das gibt es doch schon, z.B. bei Objektpascal.
> [...]try [...] finally [...] end;
Geht halt nur für Exceptions. Im normalen Ablauf hat man ja nicht so 
viele davon. Und mit Exceptions wild um sich zu werfen ist auch nicht 
die Lösung.


blablablubb schrieb:
> Bei goto ist nicht klar wohin gesprungen wird??
Nicht wenn man das Sprungziel nicht kennt. Es ann ja irgendwo stehen. 
Von daher halte ich die Verwendung von Goto für in Ordnung, wenn man 
immer nach vorne springt und idealerweise ans Ende der Funktion. Wenn 
man sich an diese Konvention hält, weiß man wo sich das Sprungziel 
befindet ohne direkt zu schauen. Das ist ja gerade der Vorteil von EXIT 
und BREAK.

von Zeno (Gast)


Lesenswert?

blablablubb schrieb:
> Das ist allerdings kein Ersatz für einen per goto gebauten
> fall-through-error-handler. (siehe Linux Kernel für Beispiele).
An dieser Stelle (Linuxkernel) kann ich nicht wirklich mit reden

Aber bei meinem Beispiel kann man, sofern Fehler passieren schon genau 
festlegen was gemacht werden soll, da ja der finally Zweig im Fehlerfall 
sofort angesprungen wird. Man wertet dann einfach die Exceptionvariable 
aus und fertig.
Man kann ja zuerst die Exceptionvariable auslesen und entsprechend 
behandeln und danach seinen Aufräumcode abarbeiten.
Was spricht dagegen das die Funktion einen Record zurückgibt, der das 
Exceptionobject und den Rückgabewert der Funktion enthält? Man hat dann 
alle Möglichkeiten der Fehlerbehandlung.

Zeno

von blablablubb (Gast)


Lesenswert?

Tommi schrieb:
> Es ann ja irgendwo stehen.

Nein kann es nicht. Es muss innerhalb in der Funktion stehen. Und wenn 
man es dort nicht findet, sollte man wegen Unfähigkeit aufhören zu 
programmieren.

> Von daher halte ich die Verwendung von Goto für in Ordnung, wenn man
> immer nach vorne springt und idealerweise ans Ende der Funktion.

So sehe ich das auch.

von blablablubb (Gast)


Lesenswert?

Zeno schrieb:
> da ja der finally Zweig im Fehlerfall
> sofort angesprungen wird.

Und es wird auch im Nicht-fehler-fall angesprungen. Und das kann ein 
Problem sein.
Einen exklusiven Fehlerpfad kann man nur mit vielen Unterfunktionen oder 
einer komplexen Unterfunktion machen, wenn man goto nicht verwendet. Und 
selbst dann ist er unschön im Vergleich mit einer 
goto-fallthrough-Lösung.

von blablablubb (Gast)


Lesenswert?

Zeno schrieb:
> Was spricht dagegen das die Funktion einen Record zurückgibt, der das
> Exceptionobject und den Rückgabewert der Funktion enthält? Man hat dann
> alle Möglichkeiten der Fehlerbehandlung.

Dagegen spricht, dass das nicht der Fall ist, den 
fall-through-error-handler behandelt. Er behandelt die Fehler 
innerhalb der Funktion.

von Zeno (Gast)


Lesenswert?

Tommi schrieb:
> Geht halt nur für Exceptions. Im normalen Ablauf hat man ja nicht so
> viele davon. Und mit Exceptions wild um sich zu werfen ist auch nicht
> die Lösung.

Also bei Objectpascal gibt jede Menge Exceptions. Es gibt aber ein paar 
Sachen wo selbige nicht generiert werden, z.B. bei den klassischen 
Dateigeschichten wie reset, close, blockread etc.. Da kann man aber 
Fehler über IOResult abfangen und sobald selbiges ungleich 0 ist eine 
Exception generieren und schon landet man im finally-Block. Das heißt ja 
jetzt nicht das man damit wild mit Exception um sich wirft.
Man kann IOResult aber auch in einer Variable speichern, die man dann im 
finally-Block abfragt.
Noch einmal der finally-Block wird immer! durchlaufen unabhängig davon 
ob eine Exeption aufgetreten ist oder nicht.

Zeno

von Zeno (Gast)


Lesenswert?

blablablubb schrieb:
> Dagegen spricht, dass das nicht der Fall ist, den
> fall-through-error-handler behandelt. Er behandelt die Fehler
> innerhalb der Funktion.

Okey! Ich kann die Fehlerbehandlung auch innerhalb der Funktion im 
finally-Block durchführen. Es ist auch kein Problem wenn während der 
Fehlerbehandlung eine andere Funktion erforderlich wäre, der 
finally-Block wird in jedem Fall vollständig durchlaufen, es sei denn 
ich produziere auch dort Fehler, dann knallt es halt. Allerdings kann 
ich auch im finally-Block kritischen Code mit try/finally oder 
try/except kapseln, d.h. ich Exceptionblöcke schachteln.

Zeno

von Daniel A. (daniel-a)


Lesenswert?

Ich denke es geht um soein Konstrukt?
1
bool do_something( const char* a, const char* b ){
2
3
  bool success = false;
4
5
  FILE* f1 = fopen(a,"r");
6
  if(!f1)
7
    goto cleanup1;
8
9
  FILE* f2 = fopen(b,"w");
10
  if(!f2)
11
    goto cleanup2;
12
13
  if( do_something_with_files(f1,f2) ){
14
    success = true;
15
  }else{
16
    goto cleanup3;
17
  }
18
19
 cleanup3:
20
  fclose(f2);
21
 cleanup2:
22
  fclose(f1);
23
 cleanup1:
24
  return success;
25
}

von Zeno (Gast)


Lesenswert?

blablablubb schrieb:
> Und es wird auch im Nicht-fehler-fall angesprungen. Und das kann ein
> Problem sein.

Es ging ja darum eine Funktion zu haben, die immer aufräumt bevor sie 
verlassen wird. War dieser Post auf den ich da geantwortet habe.

Tommi schrieb:
> Um wirklich nicht mehr in die Goto-Versuchung zu kommen, würde ich mir
> ein solches Sprachmittel wünschen (in Pseudocode):
> Procedure Foo()
>
>   if xy then EXIT
>
> POSTEXIT
>   Cleanup...
> End Procedure
>
> D.h. dass man einen Bereich am Ende der Funktion/Routine definieren
> kann, welcher bei einem Exit aus der Funktion raus noch abgearbeitet
> wird. Das hielte ich auch für sauberen Code, da klar ist, wohin
> gesprungen wird.

Naja es ist halt wie immer, man muß schon wissen was man tut. Ich 
benutze das Konstrukt gerne wenn ich Ressourcen, Zeiger etc. in jedem 
Fall freigeben möchte.

Zeno

von Zeno (Gast)


Lesenswert?

Daniel A. schrieb:
> Ich denke es geht um soein Konstrukt?

Könnte man problemlos im try/finally-Konstrukt umsetzen - vielleicht 
nicht ganz so elegant wie Du das in Deinem Beispiel gemacht hast.
Oder man macht es genauso mit goto - geht in Pascal auch.

Zeno

von blablablubb (Gast)


Lesenswert?

Daniel A. schrieb:
> Ich denke es geht um soein Konstrukt?

Fast.
Ein ähnliches Konstrukt, das im Nicht-Fehlerfall keine Aufräumarbeiten 
macht, geht mit finally nur mit zusätzlichen Krücken.

von Daniel A. (daniel-a)


Lesenswert?

blablablubb schrieb:
> Ein ähnliches Konstrukt, das im Nicht-Fehlerfall keine Aufräumarbeiten
> macht, geht mit finally nur mit zusätzlichen Krücken.

Na dann bin ich mal froh, das mein Konstrukt im (nicht) Fehlerfall alle 
Aufräumarbeiten macht ;)

: Bearbeitet durch User
von blablablubb (Gast)


Lesenswert?

Daniel A. schrieb:
> Na dann bin ich mal froh, das mein Konstrukt im (nicht) Fehlerfall alle
> Aufräumarbeiten macht ;)

Du hast es nicht verstanden.

von Daniel A. (daniel-a)


Lesenswert?

blablablubb schrieb:
> Du hast es nicht verstanden.

Ach so, es ging darum dass die Klammern bei try - finally verhindern, 
dass man ein Cleanup auslassen kann...

von Zeno (Gast)


Lesenswert?

Daniel A. schrieb:
> Ach so, es ging darum dass die Klammern bei try - finally verhindern,

Äh wo sind bei meinem try/finally Klammern ?????

Zeno

von Zeno (Gast)


Lesenswert?

blablablubb schrieb:
> Ein ähnliches Konstrukt, das im Nicht-Fehlerfall keine Aufräumarbeiten
> macht, geht mit finally nur mit zusätzlichen Krücken.

Eigentlich nicht.
1
try
2
  try
3
    ....  //beliebiger Code
4
  except
5
    ....  //aufräumen (nur im Fehlerfall)
6
  end;
7
finally
8
  ....    //alles was man sonst so noch machen will(auch bei Fehler)
9
end;


Zeno

von blablablubb (Gast)


Lesenswert?

Zeno schrieb:
> Eigentlich nicht.

ja bla.
Man kann das natürlich hinfrickeln, dass es geht. z.B. wie in deinem 
Beispiel mit einem verschachtelten try-Block. Oder mit einer 
zusätzlichen Variablen.
So elegant wie mit goto geht es allerdings nicht.

von Zeno (Gast)


Lesenswert?

blablablubb schrieb:
> So elegant wie mit goto geht es allerdings nicht.

Das habe ich ja auch nicht behauptet. Habe eigentlich von Anfang an in 
Frage gestellt ob ich Daniels Beispiel mit try so elegant hinbekomme. 
Habe im Übrigen kein Problem damit, das er es mit goto's gelöst hat. Ich 
finde ein schönes Beispiel wie man goto einsetzen kann.

Aber warte mal ab bis die Götter des Nicht-goto's wieder erwacht sind.

von Mark B. (markbrandis)


Lesenswert?

blablablubb schrieb:
> Mark B. schrieb:
>> Nochmal für alle, die es immer noch nicht verstanden haben:
>>
>> Quantität bezeugt keine Qualität.
>
> Du behauptest also ernsthaft, dass folgende Projekte qualitativ
> minderwertig sind?

Ich sage nichts anderes, als dass auch schlechter Code funktionieren 
kann. Beweise dafür gibt es hunderttausendfach. Einfach mal die Augen 
öffnen.

von Mark B. (markbrandis)


Lesenswert?

Zeno schrieb im Beitrag #4547438:
> Mark B. schrieb:
>>> Wahnsinn, dieses krasse Stümpertum überall.
>>
>> Nochmal für alle, die es immer noch nicht verstanden haben:
>>
>> Quantität bezeugt keine Qualität.
>
> Dieses Statement war doch klar - alles Stümper.
> @Timm: Hast Du etwa was anderes erwartet?

Trolle zeichnen sich unter anderem dadurch aus, dass sie anderen Leuten 
Worte in den Mund legen. Es wäre nett, wenn Du woanders weitertrollen 
könntest.

: Bearbeitet durch User
von M. K. (sylaina)


Lesenswert?

Mark B. schrieb:
> Ich sage nichts anderes, als dass auch schlechter Code funktionieren
> kann.

Warum soll denn eine Lösung mit goto schlechterer Code sein?

von blablablubb (Gast)


Lesenswert?

Mark B. schrieb:
>> Du behauptest also ernsthaft, dass folgende Projekte qualitativ
>> minderwertig sind?
>
> Ich sage nichts anderes, als dass auch schlechter Code funktionieren
> kann.

Und damit implizierst du, dass die genannten Beispiele qualitativ 
schlechten Code haben. Und das ist geradezu lächerlich.
Wenn du das nicht implizieren würdest, wäre dein Argument unbrauchbar 
für diese Diskussion, in der es um goto geht.

von Mitlesender (Gast)


Lesenswert?

Mark B. schrieb:
> Trolle zeichnen sich unter anderem dadurch aus, dass sie anderen Leuten
> Worte in den Mund legen. Es wäre nett, wenn Du woanders weitertrollen
> könntest.

Ich lasse mir von Dir nicht den Mund verbieten.

Du bist derjenige der allen anderen stümperhaftes Programmieren 
unterstellt, selbst Leuten die Software geschrieben haben, die seit 
Jahren millionenfach erfolgreich im Einsatz ist und das sogar im 
Serverbetrieb. Dafür das das Programmieren mit goto so stümperhaft ist 
läuft diese Software außerordentlich stabil und zuverlässig, wie z.B. 
der Apache Webserver, um nur ein Beispiel zu nennen. Die Leute die das 
Teil programmiert haben können also nicht so viel falsch gemacht haben.

Ich glaube Du leidest an einer gehörigen Portion Selbstüberschätzung und 
deshalb mußt Du Dich nicht wundern, wenn entsprechende Kommentare 
kommen.

Du hälst stur an Deinen Dogmen fest und bist Dir offenbar zu fein mal 
über den Tellerrand zu schauen. Aber warum solltest Du das auch tun, 
denn die anderen sind ja eh alles Deppen. Fehlt nur noch das wir Dir 
huldigen müssen.
Wir kennen mittlerweile Deine Meinung, wissen auch das Du auf selbiger 
beharrst und in diesem Sinne solltest eher Du dich trollen, da Du diesen 
Thread nicht weiter bereicherst.

Zeno

von Programmierer (Gast)


Lesenswert?

Mitlesender schrieb:
> Dafür das das Programmieren mit goto so stümperhaft ist
> läuft diese Software außerordentlich stabil und zuverlässig,

Nochmals. Wer etwas sagt, oder wieviele etwas sagen, spielt schlichtweg 
keine Rolle.

Plakatives Beispiel: Wieviele Deutsche sind der Meinung, Spinat enthalte 
besonders viel Eisen? Wie oft hat man schon gehört, Eskimos hätten 
deutlich mehr Wörter für Schnee als Europäer?

Diese Meinungen werden Millionenfach vertreten, machen sie aber dennoch 
nicht richtig. Sie sind in der Tat falsch.

Anderes Beispiel. 2+3 = 5. Daraus kannst Du aber nicht schließen, dass 
jede 5 dieser Welt die Summe aus 2+3 ist. Eine 5 kann auch die Summe aus 
1+4 sein.

Was Du machst, ist ein ganz banaler Argumentationsfehler. Aus "B folgt 
aus A" kann man eben gerade nicht schließen, "A folgt aus B".

von blablablubb (Gast)


Lesenswert?

Programmierer schrieb:
> Nochmals. Wer etwas sagt, oder wieviele etwas sagen, spielt schlichtweg
> keine Rolle.

Doch das tut es.
Wenn eine Art eine Software zu entwickeln in Millionen von Codezeilen 
äußerst erfolgreich eingesetzt wird, dann ist diese Art nicht schlecht 
oder gar stümperhaft.
Die Software ist qualitativ hochwertig und funktional korrekt.
Der Vergleich mit irgendwelchen Volksweisheiten ist deshalb nicht 
zutreffend, weil diese genannten Volksweisheiten eben nachweislich 
falsch sind. (= nicht funktional korrekt)

von S. R. (svenska)


Lesenswert?

Mark B. schrieb:
> blablablubb schrieb:
>> Aber es gibt viele legitime Einsatzgebiete für goto. Diese wurden alle
>> schon genannt und sind trivial auffindbar.
>
> Mit "viele" meinst Du sicher:
> -Kernel Hacking unter Linux
> -Kernel Hacking unter OpenBSD
> -Kernel Hacking unter FreeBSD
> -Kernel Hacking unter NetBSD
> -Kernel Hacking unter blablablubb OS

Nein, in erster Linie "Fehlerbehandlung unter Randbedingungen". In 
zweiter Linie "Performancekriterium trumpft elegant-sauberen Code" (z.B. 
Jump-Tables). In dritter Linie dann switch/case und early return, die ja 
auch nix anderes sind. Beispiele gab es genug.

Es ist bewiesen, dass man immer ohne goto auskommen kann (und sei es 
auf Kosten zusätzlicher Variablen, höherer Verschachtelungstiefe, 
zusätzlichen Funktionsaufrufen etc.) und daher wirst du immer 
argumentieren, dass man das goto dann auch wegmachen kann und der Code 
zwingend besser wird.

Und das, lieber Mark, ist Religion.

Wir sind uns hier alle einig, dass man ohne goto auskommen kann.
Wir sind uns aber nicht einig, dass man für guten Code ohne goto 
auskommen muss.

von M. K. (sylaina)


Lesenswert?

S. R. schrieb:
> Wir sind uns hier alle einig, dass man ohne goto auskommen kann.
> Wir sind uns aber nicht einig, dass man für guten Code ohne goto
> auskommen muss.

Schön geschrieben!

Programmierer schrieb:
> Nochmals. Wer etwas sagt, oder wieviele etwas sagen, spielt schlichtweg
> keine Rolle.

Richtig, das Spielt keine Rolle. Und eine Sache wird auch nicht richtig 
nur weil genügend dran glauben oder sagen es sei richtig. Die 
Contra-goto-Fraktion macht hier aber etwas ähnliches indem sie sagt, 
dass das Verwenden von goto generell schlechter Stil sei. Zumindest ich 
lese das hier zwischen den Zeilen der Contra-goto-Fraktion heraus. Man 
kann viel Mist mit goto machen, man kann es aber auch so intelligent 
benutzen wie andere Dinge von C.

von Mark B. (markbrandis)


Lesenswert?

Programmierer schrieb:
> Mitlesender schrieb:
>> Dafür das das Programmieren mit goto so stümperhaft ist
>> läuft diese Software außerordentlich stabil und zuverlässig,
>
> Nochmals. Wer etwas sagt, oder wieviele etwas sagen, spielt schlichtweg
> keine Rolle.

Exakt so ist es. Endlich mal einer, der es verstanden hat.

> Was Du machst, ist ein ganz banaler Argumentationsfehler. Aus "B folgt
> aus A" kann man eben gerade nicht schließen, "A folgt aus B".

Eben eine klassische "logical fallacy".

von Mark B. (markbrandis)


Lesenswert?

blablablubb schrieb:
> Doch das tut es.
> Wenn eine Art eine Software zu entwickeln in Millionen von Codezeilen
> äußerst erfolgreich eingesetzt wird, dann ist diese Art nicht schlecht
> oder gar stümperhaft.

Dieses Argument ist völlig an den Haaren herbei gezogen. Unter anderem 
mal goto zu verwenden ist keine "Art zu programmieren."

> Die Software ist qualitativ hochwertig und funktional korrekt.

Möchtest Du bitte den Unterschied zwischen Binary und Sourcecode 
verstehen?

Eine Software kann funktionieren, und sogar gut funktionieren - das 
heißt aber noch lange nicht, dass auch der Sourcecode dazu von einer 
hohen Qualität ist. Das sind einfach zwei verschiedene Dinge.

Die Schlussfolgerung "Weil Linux gut ist, dann muss auch die Art und 
Weise wie der Linux Kernel programmiert ist gut sein" ist schlichtweg 
unzutreffend. Das eine folgt einfach nicht aus dem anderen.

Falls Du schon mal davon gehört hast: Es gibt so genannte "Big Balls of 
Mud". Das sind Software-Systeme, die von außen betrachtet mehr oder 
weniger gut funktionieren, die aber im Inneren eine sehr bescheidene 
Qualität aufweisen.

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

: Bearbeitet durch User
von blablablubb (Gast)


Lesenswert?

Mark B. schrieb:
> Die Schlussfolgerung "Weil Linux gut ist, dann muss auch die Art und
> Weise wie der Linux Kernel programmiert ist gut sein" ist schlichtweg
> unzutreffend.

Achso. Man kann also mit schlechtem Quelltext ein gutes Binary erzeugen.
Warum also dann die Diskussion um goto und Programmierstile, wenn es 
doch egal ist, weil das Ergebnis ja ohnehin gut ist?

>Unter anderem
>mal goto zu verwenden ist keine "Art zu programmieren."

sondern?

von Mark B. (markbrandis)


Lesenswert?

blablablubb schrieb:
> Mark B. schrieb:
>> Die Schlussfolgerung "Weil Linux gut ist, dann muss auch die Art und
>> Weise wie der Linux Kernel programmiert ist gut sein" ist schlichtweg
>> unzutreffend.
>
> Achso. Man kann also mit schlechtem Quelltext ein gutes Binary erzeugen.
> Warum also dann die Diskussion um goto und Programmierstile, wenn es
> doch egal ist, weil das Ergebnis ja ohnehin gut ist?

Jemand, der Ahnung von SW-Entwicklung hat, würde eine solche Frage nicht 
stellen. Selbst der Dümmste versteht, dass es besser ist eine Codebasis 
zu haben, die gut strukturiert, gut lesbar und gut zu warten ist.

Mit solchen Dummköpfen mag ich nicht länger diskutieren. Ich bin raus.

: Bearbeitet durch User
von blablablubb (Gast)


Lesenswert?

Mark B. schrieb:
> Selbst der Dümmste versteht, dass es besser ist eine Codebasis
> zu haben, die gut strukturiert, gut lesbar und gut zu warten ist.

Genau. Und deshalb setze ich goto ein, weil es den Quellcode lesbarer 
und besser wartbar macht.

> Mit solchen Dummköpfen mag ich nicht länger diskutieren.

Lieber nicht mit Argumenten kommen, gell?

von W.S. (Gast)


Lesenswert?

Huch, da schaut man mal wieder rein - und ihr diskutiert immer noch.

S. R. schrieb:
> Wir sind uns hier alle einig, dass man ohne goto auskommen kann.
> Wir sind uns aber nicht einig, dass man für guten Code ohne goto
> auskommen muss.

Ja, ja und nochmals JA. Sowas hätte definitiv als ultimatives Schlußwort 
gelten können für diesen Thread. Aber religiös angehauchte Eiferer wie 
Mark bemerken nicht, wenn sie sich verstiegen haben.

Mitlesender schrieb:
> Ich glaube Du leidest an einer gehörigen Portion Selbstüberschätzung und
> deshalb mußt Du Dich nicht wundern, wenn entsprechende Kommentare
> kommen.

Nun ja, du Mitlesender, ich meine da eine Feinkorrektur anbringen zu 
müssen: Mark leidet nicht an seiner objektiv vorhandenen 
Selbstüberschätzung. Vielmehr leidet er darunter, daß sie beim Rest der 
Welt nicht so recht ankommen will und ihm das auch mehr oder weniger 
dezent gesagt wurde.

Aber anstatt mal in sich zu gehen und sich zu fragen, WARUM sowas wie 
"goto" in allen Progremmiersprachen (nun ja, jedenfalls in den nicht 
rein Deklarativen) vorkommt, betitelt er den Rest der Welt als 
Dummköpfe. Sind also alle Erfinder aller existierenden 
Programmiersprachen stupide Dummköpfe???

So.

Eigentlich sollte man sich mal wieder an den gesunden Menschenverstand 
erinnern. Goto gehört zum Sprachumfang und es sollte dem verständigen 
Programmierer im jeweiligen Einzelfall überlassen bleiben, ob und wo er 
es benutzt. Alle Pauschal-Verurteilungen sind Oberbockmist - und das 
sollte es hier gewesen sein.

W.S.

von Daniel A. (daniel-a)


Lesenswert?

Die Diskussion war doch von Anfang an zum scheitern verurteilt, oder hat 
irgendjemand seine goto-Meinung geändert?

https://youtu.be/YbX0wwp-nlI

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


Lesenswert?

W.S. schrieb:
> Aber anstatt mal in sich zu gehen und sich zu fragen, WARUM sowas wie
> "goto" in allen Progremmiersprachen (nun ja, jedenfalls in den nicht
> rein Deklarativen) vorkommt,

Ersetze "allen" durch "vielen", denn es gibt durchaus imperative
Programmiersprachen ohne Goto, z.B. Java, Javascript, Python, Bash,
Rust, Groovy und Swift.

von Zeno (Gast)


Lesenswert?

Mark B. schrieb:
> Dieses Argument ist völlig an den Haaren herbei gezogen. Unter anderem
> mal goto zu verwenden ist keine "Art zu programmieren."

Du kannst keine andere Meinung akzeptieren. Mehr kann man einfach nicht 
dazu sagen. Jegliche weitere Diskussion ist deshalb zwecklos.

Zeno

von Zeno (Gast)


Lesenswert?

Mark B. schrieb:
> Mit solchen Dummköpfen mag ich nicht länger diskutieren. Ich bin raus.

Wenn es keine Argumente mehr hat dann Kopf in den Sand und beleidigt 
sein. Aber in diesem Fall ist das gut so.

von (prx) A. K. (prx)


Lesenswert?

Wie man sich derart verbissen um den sinnlosen Returnwert von main() in 
Programmen für betriebssystemfreie embedded-Umgebungen streiten kann ... 
;-). Üblicherweise ist es doch so, dass der Compiler auch schon vor C99 
nicht auf einem return besteht, weil er weiss, dass hinter der 
Hauptschleife nix los ist.

von (prx) A. K. (prx)


Lesenswert?

Es gibt übrigens einen banalen Grund, weshalb man in Sprachen wie C das 
"goto" nicht gänzlich streichen sollte: C Programme werden nicht nur von 
Menschen geschrieben. In maschinell produziertem C Code kann goto 
sinnvoll bis notwendig sein.

von Zeno (Gast)


Lesenswert?

A. K. schrieb:
> ... um den sinnlosen Returnwert ...
Der Returnwert war nur "Nebenprodukt". Eigentlich ging es um die 
Verwendung von goto.
Ich meine W.S. hatte geschrieben, das er mit goto die Compilermecker 
unterdrücken kann bei gleichzeitigem Verzicht auf return 0. Mehr 
eigentlich nicht. Aber genau das hat die Hüter des "nicht goto" erst mal 
so richtig auf den Plan gerufen. Verstehen kann ich das auch nicht.

Bisher habe ich auch immer while(1) für die Endlosschleife benutzt. Das 
for(;;) kannte ich bisher nicht. Insofern hat der Thread ja doch was 
gebracht und ich habe was dazu gelernt. Ebenso kannte ich W.S.'s goto 
Lösung nicht u.a. auch aus dem Grund goto nur zu verwenden wenn es 
wirklich sinnvoll ist. Und wenn ich ganz ehrlich bin, gefällt mir diese 
goto Lösung immer besser, auch wenn sie rückwärts springt. Aber sie 
erzeugt in dem Fall durchaus verständlichen Code , der nicht weniger 
schlecht als while(1) ist und seinen Zweck erfüllt.

Das ist jedenfalls meine (abschließende) Meinung dazu. Es steht 
natürlich jedem frei das anders zu sehen und zu handhaben. Da ich das µC 
Geschäft lediglich privat betreibe muß ich mich keinen Dogmen 
unterwerfen und bin froh darüber.

Zeno

von Mark B. (markbrandis)


Lesenswert?

Zeno schrieb:
> Mark B. schrieb:
>> Mit solchen Dummköpfen mag ich nicht länger diskutieren. Ich bin raus.
>
> Wenn es keine Argumente mehr hat dann Kopf in den Sand und beleidigt
> sein. Aber in diesem Fall ist das gut so.

Ich habe wiederholt nach Beispielen gefragt, die die Aussage "GOTO kann 
richtig gut sein" untermauern. Niemand war dazu in der Lage, ein solches 
konkretes Beispiel zu liefern.

Ich bleibe dabei: Die meisten Verwender von goto verwenden es deshalb, 
weil sie nicht verstanden haben wie man Code geschickt auf möglichst 
kleine Funktionen aufteilt. Sie machen zu große Funktionen und springen 
dann innerhalb einer solchen fröhlich hin und her, anstatt die 
eigentliche Ursache für das "Springen-müssen" abzustellen.

Und ja, ich akzepziere es wenn mir jemand das Gegenteil beweist. Dann 
aber bitte nicht einfach nur behaupten, sondern auch tatsächlich 
liefern. Ein Verweis auf 384.576 Verwendungen von goto beweist gar 
nichts. Ich kann Dir zehn Milliarden Zeilen schlechten Code zeigen, 
schlechten Code mit goto, schlechten Code ohne goto, schlechten Code von 
Anfängern, schlechten Code von Leuten die seit Jahren programmieren. Was 
beweist das? Genau: Nichts.

Zeig mir:
-GUTEN Code mit goto,
-der durch Refactoring nicht mehr besser wird,
-der anerkannte Regeln des Software-Designs befolgt, so wie man sie in 
guter Literatur zu dem Thema findet.

Dann bin ich überzeugt.

Und nun gehe hin, und kaufe Dir zum ersten Mal in Deinem Leben ein Buch 
über Software-Design. Arbeite es durch, und Du wirst danach ein besserer 
Entwickler sein. Versprochen.

von (prx) A. K. (prx)


Lesenswert?

Mark B. schrieb:
> -der anerkannte Regeln des Software-Designs befolgt, so wie man sie in
> guter Literatur zu dem Thema findet.

Da die anerkannten Regeln gemeinhin goto verbieten... ;-)

von Falk B. (falk)


Lesenswert?

Self fullfilling prophecy . . .  ;-)

von Lalala (Gast)


Lesenswert?

Selbst Kernigham hat es schon etwas differenzierter ausgedrueckt als in 
die Buchfassung hier herausgelesen wIrd:
https://www.lysator.liu.se/c/bwk-tutor.html#goto

von H.Joachim S. (crazyhorse)


Lesenswert?

Ich finds praktisch. Und ich benutze es auch ab und zu, insbesonders um 
vorzeitig aus Funktionen mit Fehlercode auszusteigen (die Alternative 
wären entweder mehrere verteilte returns (das hasse ich wirklich) oder 
aufwändigere Konstrukte, die gar keinen Sinn machen, sondern nur dazu 
dienen, dass einfache goto zu vermeiden.
Ja, es geht ohne. Besser, übersichtlicher oder sicherer wird es deshalb 
nicht automatisch.

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Hallo A.K.

A. K. schrieb:
> Mark B. schrieb:
>> -der anerkannte Regeln des Software-Designs befolgt, so wie man sie in
>> guter Literatur zu dem Thema findet.
>
> Da die anerkannten Regeln gemeinhin goto verbieten... ;-)

du hast eine Smiley dran, trotzdem noch mal zur Klarstellung:

Tun sie nicht. Der einzige Beleg dazu, der von den Verpönern bisher 
geliefert wurde war MISCRA-C:2012 und ein heftiger Schuss in den Ofen. 
Denn gerade in MISRA-C ist das Goto Verbot von "mandatory" auf 
"advisory" abgestuft worden und es sind sogar neu Hinweise eingeführt 
worden, wie ein gutes Goto auszusehen hat.

vlg

 Timm

von Vintage (Gast)


Lesenswert?

Vintage ist doch in. Mit goto kommt das Basic Feeling zurück. ;-)))

von Timm R. (Firma: privatfrickler.de) (treinisch)


Lesenswert?

Programmierer schrieb:

> Nochmals. Wer etwas sagt, oder wieviele etwas sagen, spielt schlichtweg
> keine Rolle.

vielleicht solltest Du aber lieber beim Programmieren bleiben und dich 
nicht auf ungewohntes Terrain begeben?

> Plakatives Beispiel: Wieviele Deutsche sind der Meinung, Spinat enthalte
> besonders viel Eisen? Wie oft hat man schon gehört, Eskimos hätten
> deutlich mehr Wörter für Schnee als Europäer?

Die Autoren der genannten Software haben sich nicht nur an die 
Projekt-Guidelines gehalten, sondern sind auch keine Lieschen Müller. 
Wenn schon, dann müsste Dein Vergleich lauten: Wieviele Chemiker, 
Biologen und Ökotrophologen sind der Meinung, Spinat enthalte besonders 
viel Eisen und können diese Meinung unwidersprochen von ausgewiesenen 
Experten über Jahrzehnte deklamieren.

Das sieht dann schon anders aus. Was Du da gemacht hast, war nicht 
plakativ, sondern angewandter Rabulismus.

Aber Du gehörst sicher zu den Leuten, die stehen bleiben, wenn 6 Leute 
vom Kampfmittelräumdienst aus der Absperrung nebenan gesprintet kommen.


> Anderes Beispiel. 2+3 = 5. Daraus kannst Du aber nicht schließen, dass
> jede 5 dieser Welt die Summe aus 2+3 ist. Eine 5 kann auch die Summe aus
> 1+4 sein.
>
> Was Du machst, ist ein ganz banaler Argumentationsfehler. Aus "B folgt
> aus A" kann man eben gerade nicht schließen, "A folgt aus B".

Ei, das haben wir uns aber schön an den Haaren herbeigezogen. Was 
bitteschön hat ein falscher Modus tollens mit dem Gewicht von 
Autoritätsargumenten zu tun? Nicht jeder Unsinn ist mit allem verwandt, 
was Du für Unsinn hältst.

Autoritätsargumente sind nicht trivial wahr, sondern Gegenstand von 
Abwägungen, sie sind aber weder defekt noch per se falsch.


Aber: Drehen wir den Spieß doch um? Möge doch bitte einer der Verpöner 
ein großes Open Source Projekt, geschrieben in C, nennen, das kein Goto 
enthält?

Oder zumindest endlich mal eine etablierte und verbreitete Richtlinie, 
die Goto untersagt.


Vlg
 Timm

: Bearbeitet durch User
von Mark B. (markbrandis)


Lesenswert?

Timm R. schrieb:
> Aber: Drehen wir den Spieß doch um? Möge doch bitte einer der Verpöner
> ein großes Open Source Projekt, geschrieben in C, nennen, das kein Goto
> enthält?

Hm. Ein großes Projekt, geschrieben in C, mit gutem Software-Design, wo 
man bei einem Code Review nicht ständig "What the fuck?" rufen würde. 
Hat es so etwas jemals gegeben?

http://www.osnews.com/story/19266/WTFs_m

von Zeno (Gast)


Lesenswert?

Mark B. schrieb:
> Und nun gehe hin, und kaufe Dir zum ersten Mal in Deinem Leben ein Buch
> über Software-Design. Arbeite es durch, und Du wirst danach ein besserer
> Entwickler sein. Versprochen.

Du kannst es nicht lassen. Lebe weiter in Deiner Welt mit Deinem 
Fanatismus.

Gute Softwareentwickler kennen keine Dogmen, sondern lösen das Problem 
und wählen hierfür das Werkzeug/Programmiersprache mit dem/der sich die 
Aufgabe am besten lösen läßt. Ein guter Softwareentwickler wird auch den 
Sprachumfang einer Programmiersprache ausnutzen und die Sprachelemente 
wählen mit denen das Problem am effizientesten gelöst werden. Er kennt 
halt keine Dogmen und wird z.B. auch ein goto einsetzen wenn dies Sinn 
macht und zu effizienten und gut lesbaren Code beiträgt. Er wird 
hingegen ein goto nicht einsetzen, wenn es eine andere gleichwertige 
oder bessere Lösung gibt.
Letztendlich ist entscheidend, daß mit der Software das Problem gelöst 
wird und diese zuverlässig und stabil funktioniert. Mir als Anwender ist 
es völlig wurscht wie die Software die gewünschte Funktionalität 
erreicht und ob der Programmierer hierzu goto eingesetzt. Wenn die 
Funktionalität vorhanden ist und SW stabil läuft, dann hat sie für mich 
eine hohe Qualität.

Mark B. schrieb:
> Hm. Ein großes Projekt, geschrieben in C, mit gutem Software-Design, wo
> man bei einem Code Review nicht ständig "What the fuck?" rufen würde.
> Hat es so etwas jemals gegeben?

Wahrscheinlich nur, wenn diese Software von Herrn Mark Brandis 
geschrieben wurde.

Gerade in Deinem letzten Post hast Du wieder einmal bewiesen wie 
arrogant Du bist. Alle anderen scheinen ja nach Deinem Verständnis nur 
Deppen und Volltrottel zu sein.
Da gibt es nur ein Fazit : Hochmut kommt vor dem Fall.

Zeno

PS: Die Frage ist wie viele große Projekte mit qualitativ hervorragenden 
Code hast Du denn schon auf die Beine gestellt? Behaupten kann jeder 
viel.

von chris_ (Gast)


Lesenswert?

Unabhängig vom ästhetischen Befinden ob "goto's" gut oder schlecht sind, 
gibt es vielleicht ein Argument gegen "goto":

Die MISRA-Regeln verbieten es.
( Ich kann leider nur auf die Wikipedia verweisen
 - goto soll nicht verwendet werden[6]
 MISRA 1998, Regel 56 und MISRA 2004, Regel 10.4
)

Falls man also einmal den Wunsch haben sollte, in der 
Automotive-Industrie zu arbeiten, muss man wohl auf das "goto" 
verzichten.

von M. K. (sylaina)


Lesenswert?

chris_ schrieb:
> Die MISRA-Regeln verbieten es.

Nicht ganz. Sie empfiehlt nur goto nicht zu verwenden, sie verbietet die 
Verwendung aber nicht. Rule 15 behandelt die Verwendung von goto ;)

von chris_ (Gast)


Lesenswert?

>Sie empfiehlt nur goto nicht zu verwenden, sie verbietet die
>Verwendung aber nicht

Gibt es eigentlich irgendwo im Netz ein Dokument, wo man die MISRA 
Regeln einsehen kann?

von M. K. (sylaina)


Lesenswert?

chris_ schrieb:
>>Sie empfiehlt nur goto nicht zu verwenden, sie verbietet die
>>Verwendung aber nicht
>
> Gibt es eigentlich irgendwo im Netz ein Dokument, wo man die MISRA
> Regeln einsehen kann?

Google ist dein Freund: 
http://archive.redlizards.com/docs/misrac2012-datasheet.pdf

Das wäre aber jetzt auch nicht so schwer gewesen selbst zu finden.

: Bearbeitet durch User
von Mark B. (markbrandis)


Lesenswert?

Zeno schrieb:
> Gute Softwareentwickler kennen keine Dogmen

Selbstverständlich gibt es Regeln, die man als Programmierer zu 
akzeptieren hat. Exakt das unterscheidet einen guten Entwickler von 
einem schlechten: Der Gute ist in der Lage, sich an sinnvolle(!) Regeln 
zu halten. Er weiß, dass das Ergebnis seiner Arbeit dadurch besser wird. 
Der Schlechte programmiert frei Schnauze wie immer er Bock hat, und 
produziert dadurch Bockmist. Been there, done that.

Wenn Du eine bestimmte Qualität erreichen willst, ganz besonders wenn 
ein Team am Projekt arbeitet und nicht ein Einzelner, dann musst Du 
zwingend Regeln aufstellen. Sonst hast Du Wildwuchs. Jeder Programmierer 
im Projekt macht dann was er will, und entsprechend beschissen ist 
hinterher die Qualität und die Wartbarkeit des Codes.

> Mark B. schrieb:
>> Hm. Ein großes Projekt, geschrieben in C, mit gutem Software-Design, wo
>> man bei einem Code Review nicht ständig "What the fuck?" rufen würde.
>> Hat es so etwas jemals gegeben?

> Gerade in Deinem letzten Post hast Du wieder einmal bewiesen wie
> arrogant Du bist. Alle anderen scheinen ja nach Deinem Verständnis nur
> Deppen und Volltrottel zu sein.

Wer behauptet, dass C gut geeignet für große und komplexe SW-Projekte 
sei, der dokumentiert damit dass er nicht viel Ahnung von Software hat.

Die Sprache C war schlicht und ergreifend nie für große, hochkomplexe 
SW-Projekte entworfen worden, wie wir sie heute haben. Solche Projekte 
mit vielen Millionen Lines Of Code gab es damals, Ende der 60er Anfang 
der 70er Jahre, schlicht und ergreifend noch gar nicht.

Entsprechend schlecht ist C für solche Projekte ausgestattet. Das fängt 
bei den läppischen Mechanismen für die Fehlerbehandlung an, und hört bei 
der sehr zu wünschen übrig lassenden C-Standardbibliothek nicht auf. 
Schau Dir Sprachen wie Java, Python und Scala an. Was man da mit wenigen 
Zeilen fehlerfrei hinschreiben kann, dafür braucht man in C schon einen 
kleinen Urwald an Code. Viel mehr Code nötig, um im Endeffekt das 
Gleiche zu tun --> Größeres Fehlerpotenzial.

Niemand hält es heute noch für eine gute Idee, ein großes und komplexes 
SW-Projekt in einer Sprache durchzuführen, die den Entwickler so 
herzlich wenig dabei unterstützt wie C es eben tut. Außer Dir 
vielleicht(?).

C hat seine Berechtigung, wenn man hardwarenah entwickeln will und/oder 
eine sehr hohe Ausführungsgeschwindigkeit braucht. Aber selbst dann ist 
C++ oftmals die bessere Wahl. Leider kennen viele Programmierer nur ein 
Werkzeug, und "if you only have a hammer, then every problem looks like 
a nail".

> PS: Die Frage ist wie viele große Projekte mit qualitativ hervorragenden
> Code hast Du denn schon auf die Beine gestellt? Behaupten kann jeder
> viel.

Ich schreibe seit Jahren Code, der sicherheitstechnisch zertifiziert 
wird, vom TÜV und anderen Firmen einem Audit unterzogen wird und vom 
Eisenbahnbundesamt abgenommen werden muss. Ansonsten darf das 
Schienenfahrzeug mit dem entsprechenden Software-Stand eben nicht fahren 
und der Kunde springt uns ins Gesicht. Noch Fragen?

: Bearbeitet durch User
von MCUA (Gast)


Lesenswert?

>Die Sprache C war schlicht und ergreifend nie für große, hochkomplexe
>SW-Projekte entworfen worden,
hinsichtl. goto ist das Totaler Blödsinn!
Das betr. goto sind prinzipielle Dinge, die rein gar nichts mit einer 
speziellen Programmiersprache zu tun haben. Das hast du nicht kapiert.
Und den o.g. Ausschluss kannst du auch nicht machen (und für dieses 
Beispiel auch nichts besseres bringen ohne goto).
Offensichtlich redest du nur nach, was man dir vorgibt, wie auch
>Selbstverständlich gibt es Regeln, die man als Programmierer zu
>akzeptieren hat.
zeigt.

-------------------------------------
Und nochmal ganz allgemein:
Das Problem besteht (u.a), sobald von MEHREREN Stellen aus die Gleiche 
Behandlung (oder gleiche Codeteile) ausgeführt werden sollen.

von Michael B. (laberkopp)


Lesenswert?

Bitte kann man jemand diesen Titel im ersten Beitrag ändern damit der 
eklatante Rechtschreibfehler behoben wird.
Wenn der Thread nur 1 Tag aktiv wäre hätte man das überleben können, 
aber so wird man in der Forumsübersicht jeden Tag mit der Augenkrebs und 
Übelkeit verursachenden defekten Rechtscheibung des "verpönnt" 
konfrontiert, mir rollen sich da die Fussnägel auf und stülpt sich der 
Magen um.

von Mark B. (markbrandis)


Lesenswert?

MCUA schrieb:
> Das betr. goto sind prinzipielle Dinge, die rein gar nichts mit einer
> speziellen Programmiersprache zu tun haben. Das hast du nicht kapiert.

Das stimmt so nicht ganz. In C++ zum Beispiel habe ich ganz andere 
Mechanismen zur Fehlerbehandlung, eben die Exceptions. Wenn man ein 
solches Sprachmittel verwenden kann, gibt es nun wirklich keinen Grund 
mehr stattdessen goto vorzuziehen.

Java kennt kein goto.
Python kennt kein goto.

Warum haben diese Sprachen keine unbedingten Sprünge? Weil man sie nicht 
braucht - allerspätestens dann, wenn man bessere Sprachmittel zur 
Verfügung hat. Und auch vorher schon kann man ohne auskommen, wenn man 
will.

> Und den o.g. Ausschluss kannst du auch nicht machen (und für dieses
> Beispiel auch nichts besseres bringen ohne goto).
> Offensichtlich redest du nur nach, was man dir vorgibt, wie auch
>>Selbstverständlich gibt es Regeln, die man als Programmierer zu
>>akzeptieren hat.
> zeigt.
>
> -------------------------------------
> Und nochmal ganz allgemein:
> Das Problem besteht (u.a), sobald von MEHREREN Stellen aus die Gleiche
> Behandlung (oder gleiche Codeteile) ausgeführt werden sollen.

Gleiche Codeteile steckt man üblicherweise in eine eigene Funktion. Die 
kann man aufrufen, von wo immer aus man will. Welchen Vorteil bringt 
goto gegenüber dem Aufruf einer eigenständigen Funktion?

von Yalu X. (yalu) (Moderator)


Lesenswert?

Michael B. schrieb:
> Bitte kann man jemand diesen Titel im ersten Beitrag ändern damit der
> eklatante Rechtschreibfehler behoben wird.

Hab's geändert.

von Daniel A. (daniel-a)


Lesenswert?

Mark B. schrieb:
> Java kennt kein goto

Stimmt, aber dafür gibts benannte Blöcke. In JavaScript übrigens auch.
1
 // Sinnfreier Java/JavaScript code
2
a: {
3
  if(bla())
4
    break a;
5
  bla();
6
}
7
8
i=0;
9
b: do {
10
  while(i<100)
11
    if( i++ == 50 )
12
      continue b;
13
  break;
14
} while(1);

von Michael B. (laberkopp)


Lesenswert?

Yalu X. schrieb:
> Michael B. schrieb:
>> Bitte kann man jemand diesen Titel im ersten Beitrag ändern damit der
>> eklatante Rechtschreibfehler behoben wird.
>
> Hab's geändert.

Danke, der Krebs ist weg.

von steffen (Gast)


Lesenswert?

Hier mal der Ausschnitt aus den MISRA Regeln, weil sie eine sinnhafte 
Anwendung des GOTO zu beschreiben:

aus: http://archive.redlizards.com/docs/misrac2012-datasheet.pdf

Rule-15.1
The goto statement should
not be used
Advisory
Decidable
MISRAC2012-Rule-15.1
:
Uses of goto.
Rule-15.2
The goto statement shall
jump to a label declared later
in the same function
Required
Decidable
MISRAC2012-Rule-15.2
:
Backwards goto's
Rule-15.3
Any label referenced by a
goto statement shall be
declared in the same block,
or in any block enclosing the
goto statement
Required
Decidable
MISRAC2012-Rule-15.3
:
Goto's into a nested block
Rule-15.4
There should be no more
than one break or goto
statement used to terminate
any iteration statement
Advisory
Decidable
MISRAC2012-Rule-15.4
:
Two or more break or goto
statements in a loop
Rule-15.5
A function should have a
single point of exit at the end
Advisory
Decidable
MISRAC2012-Rule-15.5
:
Functions with multiple
points of exit

>M. Köhler (sylaina)
>Das wäre aber jetzt auch nicht so schwer gewesen selbst zu finden.

Diese Art Kommentar kannst Du Dir grundsätzlich sparen.

von MCUA (Gast)


Lesenswert?

>Gleiche Codeteile steckt man üblicherweise in eine eigene Funktion.
Eben nicht! Jedenfalls nicht immer.
Den Grund hatte ich schon genannt.

von M. K. (sylaina)


Lesenswert?

steffen schrieb:
> Diese Art Kommentar kannst Du Dir grundsätzlich sparen.

Da ich mir das sparen kann und nicht muss mach ich von meiner 
Möglichkeit gebrauch mir solch einen Kommentar nicht zu sparen. Wenn 
jemanden so etwas interessiert, ist es wirklich zuviel verlangt dass 
dieser dann zumindest mal MISRA in eine Suchmaschine seiner Wahl 
eingibt?

von Zeno (Gast)


Lesenswert?

Mark B. schrieb:
> Wer behauptet, dass C gut geeignet für große und komplexe SW-Projekte
> sei, der dokumentiert damit dass er nicht viel Ahnung von Software hat.

Ich habe nur einen Teil Deines Postes zitiert, um quasi einen Verweis zu 
haben, und nicht behauptet das C für große Projekte gut geeignet ich. Im 
Gegenteil ich persönlich meide C wo es nur geht, da ich von dieser 
Sprache nicht überzeugt bin. C öffnet Tür und Tor um schlecht lesbaren 
und kompromitierbaren Code zu schreiben. Es würde jetzt zu weit führen 
alle Features in C aufzuzählen die mir nicht gefallen, das ist auch 
nicht Thema des Threads und es ist meine ganz persönliche Meinung. Im 
Umkehrschluß bedeutet das jetzt nicht das alle C-Programmierer Deppen 
sind die keine Ahnung von Coden haben, wie die Vielzahl (großer und 
kleiner) Projekte beweist. Welche Programmiersprache man benutzt hängt 
auch etwas davon ab womit man "groß" geworden ist bzw. sein erstes 
größeres Projekt verwirklicht hat.
Ich hatte es schon geschrieben: Zum Schluß zählt das Endprodukt und wie 
der Programmierer dahin gekommen ist, interessiert den Anwender nicht.

C verwende ich nur zur Programmierung von µC's, weil es hierfür nichts 
anderes gibt, zumindest keinen guten Pascalcompiler.

Und um es gleich vorweg zu nehmen ich bin auch kein Freund von C++ und 
C#. Beide basieren auf C und haben letztendlich alle Unzulänglichkeiten 
von C mitgenommen. Allein die Anzahl der Zuweisungsoperatoren in C++ ist 
eine Zumutung (=, -> und dann noch die Umleitungsoperatoren) sprechen 
für sich, um nur mal ein Beispiel zu nennen. Alles nur irgendwie 
zusammen gefrickelt. In Pascal beispielsweise gibt es nur einen einzigen 
nämlich := und der gilt für alle Zuweisungen. Oder man nehme HP/HT-Basic 
her, da heißt der Zuweisungsoperator -> und fertig.
Ich will jetzt die Qualität der Programmiersprache nicht am 
Zuweisungsoperator fest machen, aber das ist mir jetzt gerade 
eingefallen als ein Feature welches mir nicht gefällt.
C# ist auch nicht besser aber ich muß es für ein große Projekt benutzen 
weil mein Arbeitgeber das wünscht.

Wie gesagt alles meine persönliche Meinung. Es darf jeder anders sehen 
und jeder soll die Programmierwerkzeuge benutzen von denen er meint, daß 
er damit seine Aufgaben am besten erfüllen kann und gut ist.
Jeglicher Fanatismus ist da fehl am Platze.

Zeno

von Zeno (Gast)


Lesenswert?

Daniel A. schrieb:
> Stimmt, aber dafür gibts benannte Blöcke. In JavaScript übrigens auch.

Letztendlich ein goto mit Tarnkappe. :-)

von Herbert P. (Gast)


Lesenswert?

M. K. schrieb:
> chris_ schrieb:
>>>Sie empfiehlt nur goto nicht zu verwenden, sie verbietet die
>>>Verwendung aber nicht
>>
>> Gibt es eigentlich irgendwo im Netz ein Dokument, wo man die MISRA
>> Regeln einsehen kann?
>
> Google ist dein Freund:
> http://archive.redlizards.com/docs/misrac2012-datasheet.pdf
>
> Das wäre aber jetzt auch nicht so schwer gewesen selbst zu finden.

Das Datasheet ist aber leider nur die halbe Wahrheit, es listet nur auf 
ohne Erläuterungen, der gesamte MISRA-C:2012 Standard hat 236 Seiten und 
ist legal nur bei MISRA zu kaufen (Kostet aber nicht die Welt: GBP 15 + 
VAT). Wie jemand schon gesagt hat (um mich genüsslich richtigzustellen, 
hatte am WoE leider nicht den Text des Standards zur Verfügung und nur 
aus dem Gedächtnis zitiert), besagt Rule 15.1 bei MISRA "The goto 
statement should not be used" und ist eine sog. Advisory-Regel. Jetzt 
ist das aber nicht bloß als eine Empfehlung abzukanzeln, sondern es 
heißt bei MISRA (sinngemäß übersetzt, Quelle: MISRA-C:2012, Kap. 6.2.3, 
S.13):

Advisory guidelines sind Empfehlungen. Das bedeutet aber nicht, dass 
diese Punkte ignoriert werden können, sondern soweit als sinnvoll 
möglich zu befolegen sind. Der Prozess für formale Abweichungen muss 
nicht eingehalten werden, aber das Nichtbefolgen ist zu dokumentieren. 
Eine Organisation kann für sich entscheiden, advisory guidelines als 
mandatory zu behandeln.

Außerdem erlaubt MISRC-C goto nur unter den folgenden Bedingungen:

- nur Vorwärtssprünge sind erlaubt (Rule 15.2)
- nur Sprünge im lokalen Block sind erlaubt (Rule 15.3)
- maximal ein goto (oder break) darf eine Schleife beenden (Rule 15.4)

Das schließt meinem Dafürhalten nach Schleifenbildung mit goto definitiv 
aus.

Grüsse
Herby

von M. K. (sylaina)


Lesenswert?

Herbert P. schrieb:
> Das Datasheet ist aber leider nur die halbe Wahrheit...
Oh, dagegen habe ich auch nichts zu sage. Ich wollte damit nur drauf 
hinweisen, dass Aussagen wie diese hier:

chris_ schrieb:
> Die MISRA-Regeln verbieten es.

schlicht falsch sind.

Zum eigentlichen Thema kann ich nur sagen, dass auch ich es gelehrt 
bekommen habe goto zu vermeiden. Ich bin in C aber bisher auch noch nie 
in die Verlegenheit gekommen, dass ich ein goto gebraucht hätte. Es lies 
sich immer vermeiden bei den Programmen, die ich schrieb. Weiter oben 
jedoch, das USB-Beispiel, ist, finde ich, mit goto ein stückweit 
lesbarer als mit den ineinander verschachtelter Schleifen. Was von 
beiden Varianten nun aber wirklich der allgemein bessere Code ist vermag 
ich nicht zu sagen.

von Falk B. (falk)


Lesenswert?

@M. Köhler (sylaina)

>Zum eigentlichen Thema kann ich nur sagen, dass auch ich es gelehrt
>bekommen habe goto zu vermeiden.

Me too. Beim Umstieg von BASIC auf Pascal in der Schule war das nicht 
vorhandene bzw. nicht erlaubte GoTo erstmal ein Schock.
Meine Reaktion "Geht doch gar nicht!!!".
Und es ging doch, und das sogar problemlos.

> Ich bin in C aber bisher auch noch nie
>in die Verlegenheit gekommen, dass ich ein goto gebraucht hätte. Es lies
>sich immer vermeiden bei den Programmen, die ich schrieb.

Me too, wenn gleich ich nicht der große Programierer bin. Meine 
Programme spielen am unteren Ende der Skala, was Umfang und Komplexität 
angeht.

> Weiter oben
>jedoch, das USB-Beispiel, ist, finde ich, mit goto ein stückweit
>lesbarer als mit den ineinander verschachtelter Schleifen.

Du vermischt was. Im USB-Beispiel war es ein Switch, die Schleifen waren 
der TCP Ausschnitt aus dem RTOS.

>Was von
>beiden Varianten nun aber wirklich der allgemein bessere Code ist vermag
>ich nicht zu sagen.

Das RTOS-Beispiel kommt ohe Goto spielend aus, ist sehr lesbar und mit 
der Erweiterung auf eine ENDLICHE Anzahl von Suchvorgängen sogar 
wasserdicht.
Das USB-Beipiel gewinnnt durch goto nur minimal an Lesbarkeit, eine 
Funktion oder das Setzen eines Flags an der Stelle wären ebenso OK und 
goto-frei ;-)

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.