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


von Bernd K. (prof7bit)


Lesenswert?

Rolf M. schrieb:
> Es gibt ja auch noch den eigentlich viel cooleren umgekehrten Konstrukt
> names COMEFROM.

Auch unter dem Namen catch oder except bekannt.

von Rolf M. (rmagnus)


Lesenswert?

Mikro 7. schrieb:
> Ob eine Meldung nutzlos ist oder nicht hängt wohl vom Betrachter ab.
> sighandler(int)
> {
>     // ...
> }

...quittiert gcc mit:
"error: parameter name omitted"
da es in C nicht gestattet ist, namenlose Parameter zu haben.

von M. K. (sylaina)


Lesenswert?

Rolf M. schrieb:
> Nein. Weil du gesagt hast, dass das der UNTERSCHIED zwischen Warnung
> und Fehler ist. Was ist daran denn so schwer zu begreifen?

Dass ich das nie geschrieben habe. Was ich nicht begreife ist wie 
Personen wie du auf so etwas kommen? Ich mein, hey. Ich wüsste jetzt 
nicht mal wie ich überhaupt einen Compiler dazu bekomme einen 
fehlerhaften Code zu übersetzen, so tief geht mein Wissen bzgl. des 
GCC-Compilers nicht. Die Aussage "Fehler soll man beseitigen." ist daher 
nach meinem Wissen auch unsinn denn "Fehler muss man beseitigen" da 
sonst erst gar kein Programm erzeugt wird.

Rolf M. schrieb:
> Nehmen wir ein anderes Beispiel: Ein unbenutzter Parameter erzeugt in
> gcc auch eine Warnung. Manchmal braucht man einen solchen aber, wenn die
> API es erfordert, z.B. wenn man eine Callback-Funktion definiert, die
> eben zwingend diesen Parameter haben muss. Oder wenn im Zuge der
> Weiterentwicklung der Parameter nicht mehr nötig ist, die API sich aber
> nicht ändern darf. Sowas passiert mir praktisch regelmäßig.

Warum darf sich denn die API nicht ändern? Den Grund dafür würde ich 
gerne mal wissen. Dass ein Compiler vor einem unbenutzten Parameter 
warnt ist doch völlig richtig und OK. Ist der Parameter unnötig dann 
gehört er da auch nicht hin. Und dein Beispiel hat noch einen Haken: 
Wenn sich die API nicht ändern darf und man einen Parameter nicht mehr 
braucht muss er ja vorher gebraucht worden sein, er dürfte gar nicht 
unbenutzt rumliegen. Wenn er jetzt aber doch unbenutzt rumliegt hat man 
die API ja doch verändert. Das klingt nach klassischem Eigentor.

Rolf M. schrieb:
> Ein gängiger
> Weg, die Warnung zu unterbinden, sieht dann etwa so aus:

Was völlig wurscht ist da der Compiler das Programm auch mit Warnung 
übersetzt. Den gezeigten Spass könntest du dir auch sparen. Statt zu 
überlegen, wie die Warnung nicht mehr angezeigt wird wäre man besser 
beraten zu überlegen wie die Warnung erst gar nicht mehr auftritt.

Rolf M. schrieb:
> Ja, mit anderen Worten: Der Compiler glaubt zu wissen, warum du das so
> gemacht hast und dass das so falsch ist. Wenn du aber einen guten Grund
> hast, musst du dir irgendeinen work-around für die falsche Warnung
> einfallen lassen.

Der Compiler sieht nur, dass das, was man da gemacht hat, keinen 
Sinn/Nutzen ergibt und er sagt hier nur "Denk nochmal drüber nach was du 
da gemacht hast.". Es gibt keine falschen Warnungen und es gibt daher 
auch keinen Grund Warnungen zu ignorieren. Warnungen ignoriert man aus 
Bequemlichkeit. Und ja, ich hab auch schon Warnungen aus Bequemlichkeit 
ignoriert.

von Einer K. (Gast)


Lesenswert?

M. K. schrieb:
> Dass ein Compiler vor einem unbenutzten Parameter
> warnt ist doch völlig richtig und OK.
Das ist richtig.

M. K. schrieb:
> Ist der Parameter unnötig dann
> gehört er da auch nicht hin.
Das ist falsch.

von Rolf M. (rmagnus)


Lesenswert?

M. K. schrieb:
> Rolf M. schrieb:
>> Nein. Weil du gesagt hast, dass das der UNTERSCHIED zwischen Warnung
>> und Fehler ist. Was ist daran denn so schwer zu begreifen?
>
> Dass ich das nie geschrieben habe. Was ich nicht begreife ist wie
> Personen wie du auf so etwas kommen?

Ich hab's doch schon mal zitiert. Es steht da schwarz auf weiß. Wie 
kannst du das denn leugnen? Aber gerne nochmal:

M. K. schrieb:
> Dussel schrieb:
>> Was ist denn dann der Unterschied zwischen einem Fehler und einer
>> Warnung, wenn man eine Warnung wie einen Fehler behandeln soll?
>
> Dass man sich darum kümmert die Warnung zu beseitigen.

Also Frage und Antwort in einem Satz zusammenefasst: "Der Unterschied 
zwischen einem Fehler und einer Warnung ist, dass man sich darum kümmert 
die Warnung zu beseitigen."

> Ich mein, hey. Ich wüsste jetzt nicht mal wie ich überhaupt einen
> Compiler dazu bekomme einen fehlerhaften Code zu übersetzen, so tief geht
> mein Wissen bzgl. des GCC-Compilers nicht.

Ich auch nicht. Deshalb wundern uns ja hier über deine Aussage, dass man 
nur Warnungen beseitigt. Wenn du das nicht so gemeint hast, ist ja ok, 
dann kannst du das ja einfach sagen. Wäre jedenfalls besser, als zu 
behaupten, du hättest es nicht so hingeschrieben.

> Rolf M. schrieb:
>> Nehmen wir ein anderes Beispiel: Ein unbenutzter Parameter erzeugt in
>> gcc auch eine Warnung. Manchmal braucht man einen solchen aber, wenn die
>> API es erfordert, z.B. wenn man eine Callback-Funktion definiert, die
>> eben zwingend diesen Parameter haben muss. Oder wenn im Zuge der
>> Weiterentwicklung der Parameter nicht mehr nötig ist, die API sich aber
>> nicht ändern darf. Sowas passiert mir praktisch regelmäßig.
>
> Warum darf sich denn die API nicht ändern? Den Grund dafür würde ich
> gerne mal wissen.

Weil noch andere Komponenten davon abhängig sind, und deren Ersteller 
sich bedankt, wenn er die umprogrammieren muss wegen eines Parameters, 
der eigentlich gar keine Rolle mehr spielt - nur damit ich keine Warnung 
in meinem Code bekomme. Aber darum geht's doch gar nicht. Von mir aus 
lass dieses Beispiel weg und belasse es bei der Callback-Funktion.

> Dass ein Compiler vor einem unbenutzten Parameter warnt ist doch völlig
> richtig und OK.

Ein unbenutzter Parameter ist erstmal kein Fehler. Es ist eben wie ich 
oben geschrieben hab: Der Hersteller des Compilers hält das für 
verdächtig und warnt deshalb. Dass der Parameter nicht benutzt wird, 
könnte ja darauf hinweisen, dass was fehlt.

> Ist der Parameter unnötig dann gehört er da auch nicht hin.

Tja, wenn äußere Zwänge ihn nötig machen, gehört er eben hin. Leider 
kommt dann aber eine Warnung, wenn man ihn nicht auch benutzt.

> Und dein Beispiel hat noch einen Haken:
> Wenn sich die API nicht ändern darf und man einen Parameter nicht mehr
> braucht muss er ja vorher gebraucht worden sein, er dürfte gar nicht
> unbenutzt rumliegen. Wenn er jetzt aber doch unbenutzt rumliegt hat man
> die API ja doch verändert. Das klingt nach klassischem Eigentor.

Wie kommst du denn darauf? Wenn die Funktion den Parameter nicht mehr 
benötigt, aber ansonsten ihre Arbeit einfach weiter ganz normal tut, was 
soll sich dann an der API geändert haben?

> Rolf M. schrieb:
>> Ein gängiger Weg, die Warnung zu unterbinden, sieht dann etwa so aus:
>
> Was völlig wurscht ist da der Compiler das Programm auch mit Warnung
> übersetzt.

Hä? Jetzt machst du mich fertig. Du schreibst doch selbst, dass man 
Warnungen beseitigt. Jetzt ist es auf einmal wurscht?

> Den gezeigten Spass könntest du dir auch sparen. Statt zu
> überlegen, wie die Warnung nicht mehr angezeigt wird wäre man besser
> beraten zu überlegen wie die Warnung erst gar nicht mehr auftritt.

Im Falle des Signalhandlers wie? Indem ich versuche, die ISO-C-Norm so 
zu beeinflussen, dass der Signalhandler die Signalnummer nicht mehr 
übergeben bekommt und dann ein Jahrzehnt warte, bis die Compiler das 
auch umgesetzt haben? Oder was schlägst du vor zu tun, wenn ein Callback 
einen Parameter nicht braucht?

> Rolf M. schrieb:
>> Ja, mit anderen Worten: Der Compiler glaubt zu wissen, warum du das so
>> gemacht hast und dass das so falsch ist. Wenn du aber einen guten Grund
>> hast, musst du dir irgendeinen work-around für die falsche Warnung
>> einfallen lassen.
>
> Der Compiler sieht nur, dass das, was man da gemacht hat, keinen
> Sinn/Nutzen ergibt

Nein, das sieht er nicht, da Compiler keine künstliche Intelligenz 
haben, die sowas erkennen könnte. Sie können nur nach einfachen Regeln 
auf typische Stolperfallen prüfen und da pauschal warnen, ohne den 
tatsächlichen Sinn oder Unsinn wirklich zu erkennen.

> und er sagt hier nur "Denk nochmal drüber nach was du da gemacht hast.".

Ok, hab ich getan und festgestellt: Ich hab hier das richtige gemacht. 
Leider geht die Warnung davon nicht weg.

> Es gibt keine falschen Warnungen und es gibt daher auch keinen Grund
> Warnungen zu ignorieren.

Natürlich gibt es falsche Warnungen. Die treten vor allem dann auf, wenn 
der Compiler anfängt, an Stellen zu warnen, die eigentlich nicht falsch 
sind sondern nur vielleicht falsch sein könnten.
Und ignorieren will ich die Warnung auch nicht, aber wenn sie an der 
Stelle unberechtigt ist, da der Code dort genau so ist, wie er sein 
muss, muss ich sie entweder ignorieren oder auf irgendeine Weise ruhig 
stellen.

von M. K. (sylaina)


Lesenswert?

Rolf M. schrieb:
> Ich hab's doch schon mal zitiert. Es steht da schwarz auf weiß. Wie
> kannst du das denn leugnen? Aber gerne nochmal:
>
> M. K. schrieb:
>> Dussel schrieb:
>>> Was ist denn dann der Unterschied zwischen einem Fehler und einer
>>> Warnung, wenn man eine Warnung wie einen Fehler behandeln soll?
>>
>> Dass man sich darum kümmert die Warnung zu beseitigen.

Ich sehe da nicht, dass ich schrieb man solle Fehler nicht beseitigen. 
Hab vielleicht was auf der Brille.

Rolf M. schrieb:
> Wenn du das nicht so gemeint hast, ist ja ok,
> dann kannst du das ja einfach sagen.

Das habe ich bereits mehrfach. Du solltest dir auch alles durchlesen was 
ich schrieb. Ich zitiere nur mal die beiden nachfolgenden Post auf den 
Post von mir, der anscheinend zur Verwirrung beitrug:

Dussel schrieb:
> M. K. schrieb:
>> Dass man sich darum kümmert die Warnung zu beseitigen.
> Und den Fehler beseitigt man nicht? :D

M. K. schrieb:
> Bei dir laufen Programme obwohl der Compiler Fehler geworfen hat?
> Beeindruckend, meiner macht da erst gar kein Hexfile draus. ;)

Und hieraus hast du jetzt ernsthaft interpretiert, dass ich sagte, dass 
man Fehler nicht beseitigen soll? Faszinierend.

Rolf M. schrieb:
> Weil noch andere Komponenten davon abhängig sind, und deren Ersteller
> sich bedankt, wenn er die umprogrammieren muss wegen eines Parameters,
> der eigentlich gar keine Rolle mehr spielt - nur damit ich keine Warnung
> in meinem Code bekomme.
Na wenn der Parameter unbenutzt ist müssen auch andere ihren Code ändern 
oder warum glaubst du dass deren Code keine Warnung ausgibt beim 
Übersetzen?

Rolf M. schrieb:
> Tja, wenn äußere Zwänge ihn nötig machen, gehört er eben hin. Leider
> kommt dann aber eine Warnung, wenn man ihn nicht auch benutzt.

Tja, wenn es mal diese Zwänge gäbe…und nein, dein Beispiel zeigt eher, 
dass du eine Funktion nicht so benutzen willst wie es vorgesehen ist.

Rolf M. schrieb:
> Wie kommst du denn darauf? Wenn die Funktion den Parameter nicht mehr
> benötigt, aber ansonsten ihre Arbeit einfach weiter ganz normal tut, was
> soll sich dann an der API geändert haben?

Du hast meine Frage an dich gut erkannt ;)
Wenn der Parameter der Funktion nicht mehr benutzt wird muss sich ja die 
Funktion der API geändert haben. Mal ein einfaches Beispiel:
1
int add (int a, int b){
2
  return a + b;
3
}

Was muss ich hier tun, dass b nicht mehr benutzt wird? Genau, ich muss 
die Funktion ändern:
1
int add (int a, int b){
2
  return a;
3
}

Selbst wenn jetzt noch andere diese API benutzen und meinen sie würden 
den Parameter b brauchen: Die Funktion ist ja auf einmal unabhängig von 
b. Deren Programm würde also nicht mehr den Erwartungen entsprechen (man 
würde ja erwarten, dass die Funktion von a und b abhängt), da ist es ja 
sogar besser wenn der Compiler einen Fehler ausgibt statt nur ne 
Warnung. Also den Parameter löschen und nicht den Code so ändern dass 
die Warnung nicht mehr angezeigt wird.

Rolf M. schrieb:
> Nein, das sieht er nicht, da Compiler keine künstliche Intelligenz
> haben, die sowas erkennen könnte. Sie können nur nach einfachen Regeln
> auf typische Stolperfallen prüfen und da pauschal warnen, ohne den
> tatsächlichen Sinn oder Unsinn wirklich zu erkennen.

Richtig, und der Compiler sieht nur dass dein Code nicht den Regeln 
entspricht.

Rolf M. schrieb:
> Ok, hab ich getan und festgestellt: Ich hab hier das richtige gemacht.
> Leider geht die Warnung davon nicht weg.

Falsch. Du hast eine Funktion mit einem Parameter den du nicht benutzt. 
Das ist nicht das Richtige sondern das Falsche. Kümmere dich drum.

Rolf M. schrieb:
> Natürlich gibt es falsche Warnungen. Die treten vor allem dann auf, wenn
> der Compiler anfängt, an Stellen zu warnen, die eigentlich nicht falsch
> sind sondern nur vielleicht falsch sein könnten.

Nein, es gibt keine falschen Warnungen. Es gibt Folgewarnungen/-fehler 
weil man schon zuvor was falsch gemacht hat. Aber da sind wir dann schon 
am Punkt dass sich nicht nur das Programm, dass man schreiben wollte, 
sich nicht erwartungsgemäß verhält sondern schon der Quellcode eine 
anderes Verhalten hat als das was man erwartet und das Ganze nur weil 
man einen Fehler gemacht hat, weil man sich nicht an die Regeln gehalten 
hat (warum auch immer)

von Mikro 7. (mikro77)


Lesenswert?

Rolf M. schrieb:

> ...quittiert gcc mit:
> "error: parameter name omitted"
> da es in C nicht gestattet ist, namenlose Parameter zu haben.

In C++ schon.

> Man muss einen völlig sinnlosen Quatsch hinschreiben, nur
> um eine nutzlose Warnung wegzubekommen.

Sinnlos?

Schon der Quelltext sollte dem Leser zeigen, dass die Variable nicht 
vergessen wurde, sondern absichtlich nicht benutzt wird. Das kann bspw. 
durch Auslassen des Namens oder dem (void) cast geschehen.

Nutzlos?

Es stellt ein potentielles Problem dar. Ich möchte grundsätzlich darüber 
informiert werden. Auch wenn es Situationen gibt wo das "nervt".

von Walter S. (avatar)


Lesenswert?

M. K. schrieb:
> Falsch. Du hast eine Funktion mit einem Parameter den du nicht benutzt.
> Das ist nicht das Richtige sondern das Falsche. Kümmere dich drum.

hast du schon Mal mit Callback Funktionen gearbeitet?
Beispielsweise übergibt eine Bildverabeitungsfunktion die Werte eines 
Pixels:

int callback(int red, int green, int blue)

ich möchte aber jetzt nur die rot-Werte verarbeiten.

Was machst Du in dem Fall mit der Warnung des Compilers?

von Mikro 7. (mikro77)


Lesenswert?

1
int callback(int red,int,int)

In C gibt es Errors statt Warnings. Dort halt mit (void) cast oder self 
assignment. Das mag "nervig" sein sorgt aber nebenbei auch für selbst 
dokumentierenden Code.

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


Lesenswert?

Walter S. schrieb:
> Was machst Du in dem Fall mit der Warnung des Compilers?
1
__attribute__((unused))

von Konrad S. (maybee)


Lesenswert?

Jörg W. schrieb:
> Walter S. schrieb:
>> Was machst Du in dem Fall mit der Warnung des Compilers?
>
>
1
__attribute__((unused))

Im Prinzip ja ... aber ein
1
(void)x;
versteht sogar der MSVC-Compiler.

von Paul B. (paul_baumann)


Lesenswert?

Jeden Tag werde ich froher darüber, nicht C oder C-Ähnliches benutzen zu 
müssen.

SCNR
-Paul-

von Konrad S. (maybee)


Lesenswert?

Paul B. schrieb:
> Jeden Tag werde ich froher darüber, nicht C oder C-Ähnliches benutzen zu
> müssen.
>
> SCNR
> -Paul-

Dann müsstest du aber doch "SNR" schreiben. ;-)

von Dussel (Gast)


Lesenswert?

M. K. schrieb:
> Ich sehe da nicht, dass ich schrieb man solle Fehler nicht beseitigen.
> Hab vielleicht was auf der Brille.

M. K. schrieb:
> Und hieraus hast du jetzt ernsthaft interpretiert, dass ich sagte, dass
> man Fehler nicht beseitigen soll? Faszinierend.
Nicht daraus, aus dem davor Geschriebenen.

Entweder verstehst du es wirklich nicht, dann kann ich nicht weiter 
helfen, weil alles zum Verstehen nötige schon ausführlich da steht, oder 
du willst provozieren, dann kann ich auch nicht helfen, weil ich mich 
davon nicht provozieren lasse.
Danke Rolf für die mehrfachen Erklärungsversuche.

von Michael S. (rbs_phoenix)


Lesenswert?

Mikro 7. schrieb:
> In C++ schon.

Ebenso in C# und PHP. Aber hier geht es ja um C.


M. K. schrieb:
> Ich sehe da nicht, dass ich schrieb man solle Fehler nicht beseitigen.
> Hab vielleicht was auf der Brille.

Indirekt schon. Jemand fragt dich, was der Unterschied zwischen einem 
Fahrrad und einem Motorrad ist. Wenn du sagst, der UNTERSCHIED liegt 
darin, dass ein Motorrad 2 Räder hat, bedeutet das gleichzeitig, dass du 
glaubst ein Fahrrad hätte keine 2 Räder (mehr oder weniger oder keine). 
Sonst wäre es ja kein Unterschied sondern eine Gemeinsamkeit. Wenn du 
also sagst, der Unterschied zwischen Fehlern und Warnungen ist, dass 
eine Warnung beseitigt werden soll, heißt es im Umkehrschluss, ein 
Fehler soll nicht beseitigt werden. Sonst wäre es kein Unterschied. Ich 
glaub aber auch, dass jeder weiß, dass du das so nicht gemeint hast, 
sondern nur sagen wolltest, dass Warnungen im allgemeinen beseitigt 
werden sollen, Fehler natürlich ebenso.


Walter S. schrieb:
> int callback(int red, int green, int blue)
>
> ich möchte aber jetzt nur die rot-Werte verarbeiten.
>
> Was machst Du in dem Fall mit der Warnung des Compilers?

Der Fehler käme aber beim Aufruf, wenn dort nur der red-Parameter 
übergeben wird. Wieso sollte hier green und blue in der Funktion nicht 
benutzt werden sollen? Die 3 Parameter deuten ja darauf hin, dass alle 3 
Farben bearbeitet werden. Dann wundert man sich ja nur, wenn das nicht 
hinten raus kommt sondern die Parameter nur nicht benutzt werden.

Sollte jemand die Funktion schon mit RGB-Werten benutzt haben und der 
Ersteller der Funktion ändert die Funktion so, dass nur Rot verarbeitet 
wird und lässt die anderen Parameter drin (damit niemand fehler beim 
compilieren bekommt), wundern sie diese, wieso nichts mit ihren Grün und 
Blau-Werten passiert.


Jörg W. schrieb:
> Walter S. schrieb:
>> Was machst Du in dem Fall mit der Warnung des Compilers?
> __attribute__((unused))

Schaltet das nicht die Warnung zu ALLEN unbenutzten Parametern/Variablen 
aus? Das bringt ja nichts, wenn man sie nur an ein/zwei stellen explizit 
haben will aber nirgends anders.


Paul B. schrieb:
> Jeden Tag werde ich froher darüber, nicht C oder C-Ähnliches benutzen zu
> müssen.
>
> SCNR
> -Paul-

Ich frag mich schon wo Moby bleibt und schreibt "Ihr seid selber Schuld 
C zu nutzen. Bei ASM gäbe es diese Frage nicht und die Programme wären 
deutlich effizienter" ;)

von Walter S. (avatar)


Lesenswert?

Michael S. schrieb:
> Sollte jemand die Funktion schon mit RGB-Werten benutzt haben und der
> Ersteller der Funktion ändert die Funktion so, dass nur Rot verarbeitet
> wird und lässt die anderen Parameter drin (damit niemand fehler beim
> compilieren bekommt), wundern sie diese, wieso nichts mit ihren Grün und
> Blau-Werten passiert.

Das Bildverarbeitungsprogramm wird sich nicht wundern wenn du nur die 
rot-Werte verarbeitest weil dich grün und blau einfach nicht 
interessieren

von M. K. (sylaina)


Lesenswert?

Michael S. schrieb:
> M. K. schrieb:
>> Ich sehe da nicht, dass ich schrieb man solle Fehler nicht beseitigen.
>> Hab vielleicht was auf der Brille.
>
> Indirekt schon.

Ja, wenn man nur den einen Post liest ist das richtig. Darauf frug man 
aber, ob man denn Fehler nicht beseitigen soll worauf ich fragte, ob 
denn ein Programm laufen würde bei dem der Compiler Fehler meldete und 
dann fing es an dass gesagt wurde ich hätte behauptet Fehler müsse man 
nicht beseitigen.
Egal, ich denk da wahrscheinlich zu kompliziert.

Michael S. schrieb:
> Der Fehler käme aber beim Aufruf, wenn dort nur der red-Parameter
> übergeben wird. Wieso sollte hier green und blue in der Funktion nicht
> benutzt werden sollen? Die 3 Parameter deuten ja darauf hin, dass alle 3
> Farben bearbeitet werden. Dann wundert man sich ja nur, wenn das nicht
> hinten raus kommt sondern die Parameter nur nicht benutzt werden.
>
> Sollte jemand die Funktion schon mit RGB-Werten benutzt haben und der
> Ersteller der Funktion ändert die Funktion so, dass nur Rot verarbeitet
> wird und lässt die anderen Parameter drin (damit niemand fehler beim
> compilieren bekommt), wundern sie diese, wieso nichts mit ihren Grün und
> Blau-Werten passiert.

Das sehe ich genauso!

Walter S. schrieb:
> Das Bildverarbeitungsprogramm wird sich nicht wundern wenn du nur die
> rot-Werte verarbeitest weil dich grün und blau einfach nicht
> interessieren

Richtig, das Programm wundert sich nicht. Aber wenn Hans-Wurst die 
Funktion liest denkt er vielleicht die Funktion verhält sich auch bei 
unterschiedlichen Grün und Blauwerten anders und der wundert sich dann 
wenn es Funktion wurscht wie die Grün- und Blauwerte sind. Da fragt man 
sich: Kommt Hans-Wurst auf die Idee, dass jemand in der tollen Funktion 
die Grün- und Blauwerte rausgeworfen hat und sucht da den Fehler oder 
fragt sich Hans-Wurst ob er nicht selbst einen Fehler gemacht hat ;)
Also ich such die Fehler immer zuerst bei meinem Code. Es würde dauern 
bis ich merke: "Hey, mein Code ist OK aber die API ist daneben." Vor 
allem bei diesem Beispiel wo es ja in der Vergangenheit auch mal 
funktioniert haben musste.

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


Lesenswert?

M. K. schrieb:
> "Hey, mein Code ist OK aber die API ist daneben."

Das API ist nicht daneben. Vielmehr nutzt das Anwendungsprogramm nicht
alle Informationen, die ihm das API über die Callback-Funktion zur
Verfügung stellt. Dazu besteht aber auch kein Zwang.

Die nächste Callback-Funktion nutzt vielleicht nur den Grün- und den
Blauwert, die übernächste alle drei Farben. Soll deswegen das API 2³=8
Callback-Schnittstellen zur Verfügung stellen, damit man immer den exakt
passen Satz von Argumenten hat?

von Falk B. (falk)


Lesenswert?

@ Yalu X. (yalu) (Moderator)

>Blauwert, die übernächste alle drei Farben. Soll deswegen das API 2³=8
>Callback-Schnittstellen zur Verfügung stellen, damit man immer den exakt
>passen Satz von Argumenten hat?

Spätestens HIER haben Leute keinen passenden Satz von Argumenten mehr 
;-)

von M. K. (sylaina)


Lesenswert?

Yalu X. schrieb:
> Das API ist nicht daneben. Vielmehr nutzt das Anwendungsprogramm nicht
> alle Informationen, die ihm das API über die Callback-Funktion zur
> Verfügung stellt. Dazu besteht aber auch kein Zwang.

Ist ja OK wenn das Anwendungsprogramm nicht alle Informationen der API 
nutzt. Aber warum sollte dann ein Parameter einer Funktion einer API 
unbenutzt sein? Ist ja OK wenn ich mich bei einer Funktion nur für das 
Verhalten in Abhängigkeit von einer Variablen interessiere. Ich wüsste 
jetzt aber auch nicht warum das ein Warning geben sollte.
Vielleicht kann mir das einer mal genau erklären.

von Einer K. (Gast)


Lesenswert?

M. K. schrieb:
> Ich wüsste
> jetzt aber auch nicht warum das ein Warning geben sollte.
> Vielleicht kann mir das einer mal genau erklären.

Da gibts nicht viel zu erklären.... das ist einfach so...

Das GCC Handbuch sagt dazu:
> unused
> This attribute, attached to a variable,
> means that the variable is meant to be
> possibly unused. GCC will not produce a
> warning for this variable.
Aus: https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Variable-Attributes.html

von Yalu X. (yalu) (Moderator)


Lesenswert?

M. K. schrieb:
> Ist ja OK wenn das Anwendungsprogramm nicht alle Informationen der API
> nutzt.

Genau das ist aber eins der Beispiele, wo ein Funktionsargument
absichtlich unbenutzt bleibt. Da der Compiler diese Absicht aber nicht
erkennen kann, liefert er trotzdem eine Warnung. Also wird man per
void-Cast oder Selbstzuweisung versuchen, diese Warnung zu beseitigen.
Darum ging es doch in der Diskussion in den letzten paar Beiträgen,
oder?

> Aber warum sollte dann ein Parameter einer Funktion einer API
> unbenutzt sein?

Was ist eine Funktion eines API? Ein API (Application Programming
Interface) ist eine Programmierschnittstelle und besteht nur aus
Funktionsproto- und Datentypen.

> Ist ja OK wenn ich mich bei einer Funktion nur für das Verhalten in
> Abhängigkeit von einer Variablen interessiere. Ich wüsste jetzt aber
> auch nicht warum das ein Warning geben sollte. Vielleicht kann mir das
> einer mal genau erklären.

Diese Frage habe ich nicht verstanden.

von Bernd K. (prof7bit)


Lesenswert?

M. K. schrieb:
> Aber warum sollte dann ein Parameter einer Funktion einer API
> unbenutzt sein?

Es geht um Callback-Funktionen.

von W.S. (Gast)


Lesenswert?

Michael S. schrieb:
> Wenn du
> also sagst, der Unterschied zwischen Fehlern und Warnungen ist, dass
> eine Warnung beseitigt werden soll, heißt es im Umkehrschluss, ein
> Fehler soll nicht beseitigt werden. Sonst wäre es kein Unterschied.

Mein Lieber, dein logisches Denkvermögen braucht mal ein bissel 
Erholung.

Also:
Der Unterschied zwischen Fehlern und Warnungen ist, daß Warnungen 
beseitigt werden sollen. Fehler hingegen MÜSSEN beseitigt werden, 
sonst gibt's keinen Objektcode, basta.

Es ist der Unterschied zwischen Sollen und Müssen.

Yalu X. schrieb:
> Genau das ist aber eins der Beispiele, wo ein Funktionsargument
> absichtlich unbenutzt bleibt. Da der Compiler diese Absicht aber nicht
> erkennen kann, liefert er trotzdem eine Warnung.

Ja. Dir ist aber klar, daß dieses so langsam über die Grenzen von C 
hinausgeht, denn typischerweise macht man Derartiges, wenn man sowas wie 
objektorientieres Programmieren in C nachbildet. Da werden eben 
innerlich unterschiedliche Objekte (hier in C eben schnöde Funktionen in 
einem struct) mit gleichem Satz an Argumenten deklariert, eben DAMIT man 
sie alle von außen auf die gleiche Weise aufrufen kann, auch wenn das 
eine oder andere Argument in der einer der konkreten Funktionen nicht 
Verwendung findet. Das sind Gefilde, mit denen klassisches C eben nicht 
rechnet und folglich gibt es damit eben Reibereien.

Aber wir waren hier ursprünglich beim Thema GOTO - gelle?
Und eine Menge Leute ereifern sich, weil sie meinen, goto grundsätzlich 
verdammen zu müssen. Klar, es gibt für fast alles einen Workaround, 
siehe als klassisches Beispiel den MIPS-Befehlsumfang. Aber sowas wie 
goto gehört seit jeher zur Grundausstattung der allermeisten 
Programmiersprachen (mal rein Deklarative ausgenommen) und das aus 
wirklich gutem Grund. Für die künstlich aufgesetzte Scheuklappe bzw. 
Einengung des eigenen Horizonts durch imperatives Verdammen von Goto 
sehe ich keinerlei Berechtigung. Nicht mal eine stichhaltige Begründung 
gibt es dafür.

W.S.

von visitor (Gast)


Lesenswert?

In den ca. 20Jahren beruflicher embedded Programmierung gab es immer 
einen Weg Konstrukte ohne goto, continue oder exit aufzubauen. Es ist 
halt zeitaufwendiger und fordert auch ein gewisses Mass an Disziplin im 
Gesamtkonzept.

Meines Erachtens ist goto nicht verpönt sondern in den meisten Fällen 
nicht notwendig, zumindest nicht bei C. Ich behaupte auch mal, dass es 
bei aktuellen Basic Dialekten nicht mehr zum guten Programmierstil 
gehoehrt, sondern nur aus Bequemlichkeit verwendet wird!

von M. K. (sylaina)


Lesenswert?

visitor schrieb:
> Meines Erachtens ist goto nicht verpönt sondern in den meisten Fällen
> nicht notwendig, zumindest nicht bei C.

Ich würde sogar noch einen Punkt weiter gehen: goto ist in allen Fällen 
nicht notwendig.
Bei geschickter Anwendung jedoch kann es den Code lesbarer machen (bei 
so 10 ineinandere verschachtelter Schleifen/Bedingungen kann es schon 
unübersichtlich werden).

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


Lesenswert?

M. K. schrieb:
> Ich würde sogar noch einen Punkt weiter gehen: goto ist in allen Fällen
> nicht notwendig. Bei geschickter Anwendung jedoch kann es den Code
> lesbarer machen

Da war Donald Knuth schon 1974. :-)

(Damals gab es auch noch Effizienzgründe bspw. gegen die Verwendung
einer Hilfsvariablen.  Die sind mittlerweile weitgehend entfallen,
da die Compiler besser sind als damals.)

: Bearbeitet durch Moderator
von nicht"Gast" (Gast)


Lesenswert?

M. K. schrieb:
> Bei geschickter Anwendung jedoch kann es den Code lesbarer machen (bei
> so 10 ineinandere verschachtelter Schleifen/Bedingungen kann es schon
> unübersichtlich werden).

Wenn du 10 ineinander verschachtelte Schleifen und Bedingungen hast, 
dann ist schon vorher etwas grundlegend falsch gemacht worden.
Die Lösung dazu sollte ein Redesign sein und kein Goto^^.


Grüße.

von nichtCler (Gast)


Lesenswert?

nicht"Gast" schrieb:
> M. K. schrieb:
>> Bei geschickter Anwendung jedoch kann es den Code lesbarer machen (bei
>> so 10 ineinandere verschachtelter Schleifen/Bedingungen kann es schon
>> unübersichtlich werden).
>
> Wenn du 10 ineinander verschachtelte Schleifen und Bedingungen hast,
> dann ist schon vorher etwas grundlegend falsch gemacht worden.
> Die Lösung dazu sollte ein Redesign sein und kein Goto^^.

Oder aber auch das Redesign mit Goto. *ich lach mich schlapp über diese 
Diskussion hier*

von nicht"Gast" (Gast)


Lesenswert?

nichtCler schrieb:
> Oder aber auch das Redesign mit Goto

Das Problem ist aber nicht goto, sondern die zu vielen verschachtelten 
Schleifen. Das kann gar nicht lesbar sein. Auch nicht mit gotos drin.

nichtCler schrieb:
> *ich lach mich schlapp über diese
> Diskussion hier*

gab schon schlimmere Diskussusionen hier :).

von Heinz L. (ducttape)


Lesenswert?

nicht"Gast" schrieb:
> M. K. schrieb:
>> Bei geschickter Anwendung jedoch kann es den Code lesbarer machen (bei
>> so 10 ineinandere verschachtelter Schleifen/Bedingungen kann es schon
>> unübersichtlich werden).
>
> Wenn du 10 ineinander verschachtelte Schleifen und Bedingungen hast,
> dann ist schon vorher etwas grundlegend falsch gemacht worden.
> Die Lösung dazu sollte ein Redesign sein und kein Goto^^.
>
>
> Grüße.

10 ineinander geschachtelte Schleifen sind üblicherweise ein Zeichen 
dafür dass beim Design irgendwo Murks gebaut wurde.

Im Endeffekt ist die Lösung dafür üblicherweise das Ganze in eine 
Funktion zu stopfen und diese sauber mit einem return zu verlassen 
wenn's notwendig wird das vorzeitig zu terminieren.

von nicht"Gast" (Gast)


Lesenswert?

Heinz L. schrieb:
> 10 ineinander geschachtelte Schleifen sind üblicherweise ein Zeichen
> dafür dass beim Design irgendwo Murks gebaut wurde.
>
> Im Endeffekt ist die Lösung dafür üblicherweise das Ganze in eine
> Funktion zu stopfen und diese sauber mit einem return zu verlassen
> wenn's notwendig wird das vorzeitig zu terminieren.

Kannst du das nicht anders ausdrücken?^^

Du schreibst im Grunde das gleiche wie ich nur klingt es so, als ob du 
mir widersprichst. Das ist echt gruselig :)

von M. K. (sylaina)


Lesenswert?

Heinz L. schrieb:
> 10 ineinander geschachtelte Schleifen sind üblicherweise ein Zeichen
> dafür dass beim Design irgendwo Murks gebaut wurde.

Echt? Also ich könnte mir durchaus vorstellen wenn A wahr ist dann 
durchlaufe B und prüfe bei jedem Durchgang ob C erfüllt ist. Und so 
etwas kann ich mir auch durchaus legitim als noch etwas komplexer 
erachten. Von Murks würde ich da nicht sprechen.
Die "10" waren übrigens fiktiv. Und ja, ich kann auch kein Beispiel 
liefern, wo nur ein goto als sinnvoll ist.

nicht"Gast" schrieb:
> Die Lösung dazu sollte ein Redesign sein und kein Goto^^.

Sag das mal dem Quellcode deines Betriebssystems bzw. deren 
Programmierer oder hast du dein eigenen Betriebssystem geschrieben ganz 
ohne goto? ;)

von Heinz L. (ducttape)


Lesenswert?

M. K. schrieb:
> Echt? Also ich könnte mir durchaus vorstellen wenn A wahr ist dann
> durchlaufe B und prüfe bei jedem Durchgang ob C erfüllt ist. Und so
> etwas kann ich mir auch durchaus legitim als noch etwas komplexer
> erachten. Von Murks würde ich da nicht sprechen.
> Die "10" waren übrigens fiktiv. Und ja, ich kann auch kein Beispiel
> liefern, wo nur ein goto als sinnvoll ist.

Schreib den entsprechenden Code, ich schreib's dann in meine Version 
davon um und wir lassen mal abstimmen was lesbarer ist.

von M. K. (sylaina)


Lesenswert?

Heinz L. schrieb:
> Schreib den entsprechenden Code, ich schreib's dann in meine Version
> davon um und wir lassen mal abstimmen was lesbarer ist.

Was war an

M. K. schrieb:
> Und ja, ich kann auch kein Beispiel
> liefern, wo nur ein goto als sinnvoll ist.

nicht verständlich?

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


Lesenswert?

Heinz L. schrieb:
> Schreib den entsprechenden Code, ich schreib's dann in meine Version
> davon um und wir lassen mal abstimmen was lesbarer ist.

Fang' doch bitte lieber an, die 10000e gotos in *BSD und Linux
umzuschreiben, wenn du denkst, dass du dir damit Freunde machst.
Die Zählung für FreeBSD hatte ich weiter oben präsentiert, hier noch
die für Linux:
1
% find ~/src/linux-3.13 -name '*.c' | xargs fgrep -w goto | wc -l
2
114601

von Karl (Gast)


Lesenswert?

Die ganze Diskussion ist sinnlos. wie man an den Ursprüngen von Fotran 
sehen kann sind alle Schleifen und Zweige nur verkappte 
GOTO-Anweisungen.

https://de.wikibooks.org/wiki/Fortran:_FORTRAN_77:_Verzweigungen_und_Schleifen#Weitere_Schleifen

Ob man also GOTO oder was anderes verwendet ist reine syntaktische 
Kosmetik!

von nicht"Gast" (Gast)


Lesenswert?

Jörg W. schrieb:
> Fang' doch bitte lieber an, die 10000e gotos in *BSD und Linux
> umzuschreiben, wenn du denkst, dass du dir damit Freunde machst.
> Die Zählung für FreeBSD hatte ich weiter oben präsentiert, hier noch
> die für Linux:

und wieder... (seufz)

die Gotos im Linux Source werden dazu benutzt, um das fehlende error 
handling in C auszugleichen. Ich denke nicht, dass irgend wer hier damit 
ein Problem hat.

Was hier aber bisher an Beispielen kam bei denen goto die Lesbarkeit 
verbesern soll, taugt nur zum Fußnägel schneiden. Die rollen sich beim 
Betrachten gerne mal auf und sind gut erreichbar :)


Deswegen die Forderung einen beliebigen eigenen Code reinzustellen und 
dann schauen wir mal, welcher ohne goto schlechter lesbar ist.

von Mark B. (markbrandis)


Lesenswert?

nicht"Gast" schrieb:
> Deswegen die Forderung einen beliebigen eigenen Code reinzustellen und
> dann schauen wir mal, welcher ohne goto schlechter lesbar ist.

Dem schließe ich mich an. Bitte ein Beispiel zeigen, welches kein 
Spezialfall ist. Betriebssysteme sind ein Spezialfall, denn die meisten 
Softwareentwickler werden in ihrem ganzen Leben keine einzige Zeile Code 
dafür schreiben.

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


Lesenswert?

nicht"Gast" schrieb:
> die Gotos im Linux Source werden dazu benutzt, um das fehlende error
> handling in C auszugleichen.

Hast du auch alle 114601 davon einzeln kontrolliert?

Ich versteh' nicht, warum jemand dir hier die Berechtigung beweisen
müsste, ein bestimmtes Feature der Sprache gelegentlich zu nutzen,
wenn es zwei sehr prominente Opensource-Projekte erwiesenermaßen
10000- oder gar 100000fach benutzen.  Es ist doch völlig egal, wofür
es der einzelne benutzt, allein diese Zahlen zeigen, dass es
gelegentlich durchaus sinnvoll sein kann, das so zu machen, statt
irgendwelche anderen Verrenkungen zu vollführen.

Und nein, Betriebssystemcode ist auch erstmal ganz normaler Sourcecode.
Es gibt nur wenige Dinge im Betriebssystemkern, die da eine großartige
Sonderbehandlung erfahren, und diese sind in aller Regel weitgehend
in der Infrastruktur (Headerfiles etc.) abstrahiert.  Als Programmierer
schreibe ich dort erstmal C-Code im Rahmen eines vorgegebenen APIs.
(@Mark: Been there, done that.)

von Mark B. (markbrandis)


Lesenswert?

Alleine dass etwas benutzt wird, heißt noch nicht dass es so richtig 
ist. Nicht einmal dann, wenn dies häufig geschieht. Häufige Verwendung 
ist keine qualitative Wertung, sondern eine quantitative.

Es gibt zum Beispiel nicht wenige Programmierer, die ein Dutzend 
Funktionalitäten in eine einzige Funktion packen. Jeder, der Ahnung von 
Software-Design hat weiß, dass man so nicht programmiert.

Aber das ist ein generelles Problem von Software: Sie kann auch dann 
funktionieren, wenn der Code eine schlechte Qualität aufweist. Und die 
ultimative Metrik für Softwarequalität hat man noch nicht gefunden. Man 
hat aber in den letzten Jahrzehnten durchaus Erkenntnisse gewonnen, wie 
man es besser macht. Nur werden diese eben von vielen Programmierern 
fröhlich ignoriert. ;-)

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


Lesenswert?

Karl schrieb:
> Ob man also GOTO oder was anderes verwendet ist reine syntaktische
> Kosmetik!

Ja, aber gerade die Anwendung dieser syntaktischen Kosmetik entscheidet
oft über Übersichtlicheit oder Chaos im Quellcode.

Wenn man die von höheren Programmiersprachen angebotenen syntaktischen
Konstrukte (While-, For-Schleifen) nur deswegen nicht nutzt, weil sie
redundant sind und durch primitivere (Goto) ersetzt werden können, kann
man auch gleich bei Assembler bleiben.

von nicht"Gast" (Gast)


Lesenswert?

Jörg W. schrieb:
> Hast du auch alle 114601 davon einzeln kontrolliert?

Ich geb ja zu, dass ich nur in so ca 60Dateien bisher geschaut habe und 
von da aus ein wenig "interpoliert" ^^.

Du kannst dich ja mit Googleein wenig informieren. Die Diskussion um 
goto im Kernel ist zielmich lebendig, wobei Linus und der harte Kern 
natürlich eine, ich nenne es mal, gefestigte Meinung haben :)

von Clemens M. (panko)


Lesenswert?

1
void usb_process_request(void)
2
{
3
  U8 bRequest;
4
5
  Usb_reset_endpoint_fifo_access(EP_CONTROL);
6
  bmRequestType = Usb_read_endpoint_data(EP_CONTROL, 8);
7
  bRequest      = Usb_read_endpoint_data(EP_CONTROL, 8);
8
9
  switch (bRequest)
10
  {
11
  case GET_DESCRIPTOR:
12
    if (bmRequestType == 0x80) usb_get_descriptor();
13
    else goto unsupported_request;
14
    break;
15
16
  case GET_CONFIGURATION:
17
    if (bmRequestType == 0x80) usb_get_configuration();
18
    else goto unsupported_request;
19
    break;
20
21
  case SET_ADDRESS:
22
    if (bmRequestType == 0x00) usb_set_address();
23
    else goto unsupported_request;
24
    break;
25
26
  case SET_CONFIGURATION:
27
    if (bmRequestType == 0x00) usb_set_configuration();
28
    else goto unsupported_request;
29
    break;
30
31
  case CLEAR_FEATURE:
32
    if (bmRequestType <= 0x02) usb_clear_feature();
33
    else goto unsupported_request;
34
    break;
35
36
  case SET_FEATURE:
37
    if (bmRequestType <= 0x02) usb_set_feature();
38
    else goto unsupported_request;
39
    break;
40
41
  case GET_STATUS:
42
    if (0x7F < bmRequestType && bmRequestType <= 0x82) usb_get_status();
43
    else goto unsupported_request;
44
    break;
45
46
  case GET_INTERFACE:
47
    if (bmRequestType == 0x81)
48
    {
49
      if(!usb_get_interface())
50
      {
51
        Usb_enable_stall_handshake(EP_CONTROL);
52
        Usb_ack_setup_received_free();
53
      }
54
    }
55
    else goto unsupported_request;
56
    break;
57
58
  case SET_INTERFACE:
59
    if (bmRequestType == 0x01) usb_set_interface();
60
    else
61
      goto unsupported_request;
62
    break;
63
64
  case SET_DESCRIPTOR:
65
  case SYNCH_FRAME:
66
  default:  //!< unsupported request => call to user read request
67
  unsupported_request:
68
    if (!usb_user_read_request(bmRequestType, bRequest))
69
    {
70
      Usb_enable_stall_handshake(EP_CONTROL) ;
71
      Usb_ack_setup_received_free();
72
    }
73
    break;
74
  }
75
}

Das hat z.B. Atmel so rausgebracht. Ich muss zugeben, dass die 
Frameworks teilweise auch sehr zusammengeschustert sind, aber so wie 
hier benutze -ich persönlich- goto schon mal sehr gerne.
Natürlich kann man klammern bis der Arzt kommt, aber übersichtlicher 
finde ich das nicht. Bin aber lernwillig und maße mir nicht an, die 
ultimatice Meinung zu haben.
Von daher wäre ein umschreiben wie oben angeboten sicher eine mögliche 
Inspiration!

edit: und bitte kein flag einführen, was dann nach dem switch abgefragt 
wird oder so was. Das hat für mich keinen Mehrwert an der Stelle

: Bearbeitet durch User
von Rudi D. (rudi_d)


Lesenswert?

Für das error Handling macht goto Sinn, siehe z.B die Linux 
Treiberprogrammierung. Auch bei der Programmierung endlicher Automaten 
gibt es sinnvolle Modelle welche mit goto realisiert werden. Ansonsten 
wage ich zu behaupten Finger weg von goto!

von Heinz L. (ducttape)


Lesenswert?

Clemens, das ist auch wieder was das darum bettelt in eine Funktion 
verpackt zu werden und über den Rückgabewert Erfolg oder Misserfolg zu 
liefern.

von Mark B. (markbrandis)


Lesenswert?

Heinz L. schrieb:
> Clemens, das ist auch wieder was das darum bettelt in eine Funktion
> verpackt zu werden und über den Rückgabewert Erfolg oder Misserfolg zu
> liefern.

Eben. Wenn man sowieso immer an die gleiche Stelle springt und da immer 
das gleiche tut, dann kann man den Code für diesen Fall doch auch gleich 
in einer Funktion kapseln.

Also das ist nun wirklich kein Beispiel in dem goto sinnvoll ist.

: Bearbeitet durch User
von Zeno (Gast)


Lesenswert?

M. K. schrieb:
> Was muss ich hier tun, dass b nicht mehr benutzt wird? Genau, ich muss
> die Funktion ändern:
> int add (int a, int b){
>   return a;
> }
>
> Selbst wenn jetzt noch andere diese API benutzen und meinen sie würden
> den Parameter b brauchen: Die Funktion ist ja auf einmal unabhängig von
> b. Deren Programm würde also nicht mehr den Erwartungen entsprechen (man
> würde ja erwarten, dass die Funktion von a und b abhängt)

Es gibt Fälle, wo ein Parameter stehen bleiben muß oder besser sollte, 
obwohl er eigentlich nicht mehr benutzt wird. Ich habe ein Programm 
geschrieben, wo unter anderem die Messunsicherheit berechnet wird. Diese 
ist von verschiedenen Parametern abhängig, unter anderem von der 
Temperatur am Anfang der Messung und am Ende der Messung. Jetzt hat sich 
die ISO zur Berechnung der Unsicherheit geändert und die Temperatur am 
Ende der Messung wird nicht mehr berücksichtigt. Demzufolge fällt sie in 
der Berechnungsformel weg, d.h. sie ist für die Berechnung nicht mehr 
notwendig. Obwohl dieser Parameter wegfällt gibt die Funktion immer noch 
die berechnete Unsicherheit zurück. Das Programm ist sehr groß und ich 
müßte den Aufruf an vielen Stellen ändern. Die Funktion ist in einer 
eigenen Unit/Codedatei implementiert und wird auch von anderen 
Programmen benutzt. Zudem wird diese Funktion auch von einer DLL für 
andere Programme bereitgestellt. Jetzt müßte also jeder der diese DLL 
benutzt seinen Quelltext ändern. Das ist viel zu aufwändig und hier 
dürfte es wohl der bessere Weg sein die Warning zu ignorieren.

von Zeno (Gast)


Lesenswert?

Karl schrieb:
> Die ganze Diskussion ist sinnlos. wie man an den Ursprüngen von Fotran
> sehen kann sind alle Schleifen und Zweige nur verkappte
> GOTO-Anweisungen.

Karl hat es auf den Punkt gebracht. Eigentlich sind alle Schleifen und 
Verzweigungen letzendlich GOTO's und wenn man sich den generierten 
Assemblercode anschaut, dann werden solche Sachen i.d.R. in 
Sprunganweisungen umgesetzt  und ob ich nun sage "springe zu A" oder 
"Gehe zu A" ist im Endeffekt das Gleiche.

Den schlechten Ruf hat sich GOTO eigentlich nur durch Basic eingefangen. 
Z.B. gab es in den Fortrandialekten der Endsiebziger keine vernünftigen 
Kontrollstrukturen, so daß dort zwingend mit GOTO gearbeitet werden 
mußte.

Wenn man gewisse Dinge (z.B. nicht aus while-, for-, 
switch/case-Schleifen oder Funktionen herausspringen) beachtet spricht 
nichts gegen GOTO.

Es gibt Situationen wo der Einsatz von GOTO durchaus sinnvoll und alles 
andere nur Krampf ist, auch wenn dies sehr sehr selten der Fall ist. Ja 
und es gibt keinen Grund warum sich wegen des Einsatzes von GOTO schämen 
müßte.

Zeno

von Paul B. (paul_baumann)


Lesenswert?

Zeno schrieb:
> Eigentlich sind alle Schleifen und
> Verzweigungen letzendlich GOTO's und wenn man sich den generierten
> Assemblercode anschaut, dann werden solche Sachen i.d.R. in
> Sprunganweisungen umgesetzt  und ob ich nun sage "springe zu A" oder
> "Gehe zu A" ist im Endeffekt das Gleiche.

Jawoll!
Lange hat es gedauert, bis diese Wahrheit ausgesprochen wurde.

MfG Paul

von Marc (Gast)


Lesenswert?

Mich wundert immer wieder, welche alten Kamellen hier diskutiert werden.
Das Thema ist doch jetzt wirklich durch und dieses Forum wird vermutlich 
außer persönlichen Meinungen nicht den Stein der Programmierer finden,

Um trotzdem nicht als reiner Nörgler dazu stehen:
Der verlinkte Artikel beschreibt das eigentliche Problem dahinter recht 
gut:

http://www.drdobbs.com/jvm/programming-with-reason-why-is-goto-bad/228200966

Gruß
Marc

von W.S. (Gast)


Lesenswert?

Mark B. schrieb:
> Bitte ein Beispiel zeigen, welches kein
> Spezialfall ist. Betriebssysteme sind ein Spezialfall, denn die meisten
> Softwareentwickler werden in ihrem ganzen Leben keine einzige Zeile Code
> dafür schreiben.

Ach, wo sind wir hier eigentlich???

Ja, im Mikrocontroller-Forum. Eben.

Was wir hier schreiben, IST Betriebssystem - nämlich die Firmware für 
einen µC. Ich räume ein, daß es sich zumeist um ganz kleine 
Betriebssysteme handelt, viel kleiner als das, was auf viel größeren 
Anlagen läuft.

Aber es ist dennoch ein Betriebssystem und ich hatte ein richtig 
zutreffendes Beispiel mit dem GOTO in der Grundschleife von main 
gepostet.

Dort gehört das hin, weil damit der logische Knackpunkt beseitigt ist, 
der sich zwischen dem niemals Zurückkehren und dem aus Prinzip 
eingeforderten Returnwert auftut. So nebenher zeigt uns dieses Beispiel, 
daß die millionenfach geübte Praxis, auf einem µC überhaupt ein main zu 
haben, durchaus auf den Prüfstand gehört. Alternativ, ob main auf dem µC 
überhaupt int sein muß oder besser void.

W.S.

von Zeno (Gast)


Lesenswert?

W.S. schrieb:
> auf einem µC überhaupt ...


Und wenn man aus dem µC einen µP macht dann gehört eigentlich noch was 
ganz anderes auf den Prüfstand !

Zeno

von Mark B. (markbrandis)


Lesenswert?

W.S. schrieb:
> Ach, wo sind wir hier eigentlich???
>
> Ja, im Mikrocontroller-Forum. Eben.
>
> Was wir hier schreiben, IST Betriebssystem

Das sehe ich anders.

> - nämlich die Firmware für einen µC. Ich räume ein, daß es sich zumeist
> um ganz kleine Betriebssysteme handelt, viel kleiner als das, was auf
> viel größeren Anlagen läuft.

Auch bei mir ist die Vorlesung über Betriebssysteme nun schon diverse 
Jahre her. Das war übrigens die Vorlesung, in der Du immer geschlafen 
hast und ich nur selten ;-)

Aus dem Gedächtnis abgerufen hat ein Betriebssystem die folgenden 
Aufgaben:

-Verwalten des Speichers
-Verwalten des Dateisystems
-Verwalten von Benutzern
-Verwalten von Prozessen
-Abstrahieren von Hardware durch Bereitstellung von Schnittstellen, 
damit man auf eben diese Hardware zugreifen kann (z.B. PCI, ISA, RS232, 
Tastatur, Maus, Display, ...)

> So nebenher zeigt uns dieses Beispiel,
> daß die millionenfach geübte Praxis, auf einem µC überhaupt ein main zu
> haben, durchaus auf den Prüfstand gehört. Alternativ, ob main auf dem µC
> überhaupt int sein muß oder besser void.

Es mag vielleicht eine etwas unglückliche Konvention sein, dass main() 
laut Standard zwingend einen Rückgabewert haben soll. Ich persönlich 
hätte nichts gegen ein void main() einzuwenden.

Warum diese Eigenheit der Programmiersprache C für die Verwendung von 
goto sprechen soll, erschließt sich mir nicht so recht.

von Mark B. (markbrandis)


Lesenswert?

Zeno schrieb:
> Es gibt Situationen wo der Einsatz von GOTO durchaus sinnvoll und alles
> andere nur Krampf ist, auch wenn dies sehr sehr selten der Fall ist.

Wir warten immer noch auf ein wirklich gutes Beispiel, welches diese 
Aussage untermauert.

von Zeno (Gast)


Lesenswert?

Mark B. schrieb:
> Wir warten immer noch auf ein wirklich gutes Beispiel, welches diese
> Aussage untermauert.

Warum soll ich jetzt auf Krampf ein Beispiel kreieren.
Und ob das dann wirklich gut ist steht schon mal wieder auf einem 
anderen Blatt. Das entscheidet jeder eh für sich. Der der stur auf der 
Nichtverwendung von GOTO beharrt, wird definitiv eine andere Lösung 
finden und im Nachgang behaupten sie sei besser, allein schon deswegen 
weil sie GOTO vermeidet - koste es was es wolle.

Im übrigen gebe ich W.S. recht, die FW auf dem µC ist schon ein kleines 
Betriebssystem, denn es werden sehr wohl die Hardwareressourcen (Ports, 
Speicher etc.) verwaltet. Letztendlich wird auch hier die Hardware 
abstrahiert damit sie benutzt werden kann und wenn es nur ein simpler 
Schalter ist der an einem Port angeschlossen ist. Natürlich werden auf 
dem µC keine Benutzer verwaltet und ja es werden auch keine Prozesse 
verwaltet, weil nur ein Prozess nämlich die FW selbst läuft.
DOS verwaltetet(e) auch keine Benutzer und es lief i.d.R. auch nur ein 
Prozess und es war dennoch ein BS.


Zeno

von MCUA (Gast)


Lesenswert?

>Aus dem Gedächtnis abgerufen hat ein Betriebssystem die folgenden
>Aufgaben:
>-Verwalten des Speichers
>-Verwalten des Dateisystems
>-Verwalten von Benutzern
>-Verwalten von Prozessen
<-Abstrahieren von Hardware
Das kann, muss aber nicht.
Genaugenommen sind auch "kleine" uC-Programme, die ohne Aufsatz laufen, 
Betriebssysteme, mehr oder weniger komplex.

>Wir warten immer noch auf ein wirklich gutes Beispiel, welches diese
>Aussage untermauert.
Wie schon geschrieben, bsp. mehrere if-Abfragen hintereinander, ohne 
expliz. Schachtelungen, mit gemeinsamen Sprungziel.

von Mark B. (markbrandis)


Lesenswert?

MCUA schrieb:
> Wie schon geschrieben, bsp. mehrere if-Abfragen hintereinander, ohne
> expliz. Schachtelungen, mit gemeinsamen Sprungziel.

Warum sollte das Sprungziel keine eigenständige Funktion sein? Was 
spricht dagegen?

von Programmierer (Gast)


Lesenswert?

Clemens M. schrieb:

  [Wieder ganz viel Mist gelöscht]

> Das hat z.B. Atmel so rausgebracht. Ich muss zugeben, dass die
> Frameworks teilweise auch sehr zusammengeschustert sind, aber so wie
> hier benutze -ich persönlich- goto schon mal sehr gerne.

Hier sieht man wieder zwei Dinge:

a.) Wie oft und durch wen irgendetwas vorgemacht wird, sagt nichts, aber 
auch gar nichts über Qualität aus.

b.) Auch das ist wieder ein Beispiel dafür, dass "goto" schwache 
Programmierer zur dunklen Seite lockt.


> Von daher wäre ein umschreiben wie oben angeboten sicher eine mögliche
> Inspiration!
>
> edit: und bitte kein flag einführen, was dann nach dem switch abgefragt
> wird oder so was.

Wie immer, die Lösung ist so extrem simpel:

1
void usb_process_request(void)
2
{
3
    U8 bRequest;
4
5
    Usb_reset_endpoint_fifo_access(EP_CONTROL);
6
    bmRequestType = Usb_read_endpoint_data(EP_CONTROL, 8);
7
    bRequest      = Usb_read_endpoint_data(EP_CONTROL, 8);
8
9
    if (bRequest == GET_DESCRIPTOR && bmRequestType == 0x80)
10
        usb_get_descriptor();
11
12
    else if (bRequest == GET_CONFIGURATION && bmRequestType == 0x80)
13
        usb_get_configuration();
14
15
    else if (bRequest == SET_ADDRESS && bmRequestType == 0x00)
16
        usb_set_address();
17
18
    else if (bRequest == SET_CONFIGURATION && bmRequestType == 0x00) 
19
        usb_set_configuration();
20
21
    else if (bRequest == CLEAR_FEATURE && bmRequestType <= 0x02) 
22
        usb_clear_feature();
23
24
    else if (bRequest == SET_FEATURE && bmRequestType <= 0x02) 
25
        usb_set_feature();
26
27
    else if (bRequest == GET_STATUS && 0x7F < bmRequestType && bmRequestType <= 0x82) 
28
        usb_get_status();
29
30
    else if (bRequest == GET_INTERFACE && bmRequestType == 0x81)
31
    {
32
        if(!usb_get_interface())
33
        {
34
            Usb_enable_stall_handshake(EP_CONTROL);
35
            Usb_ack_setup_received_free();
36
        }
37
    }
38
39
    else if (bRequest == SET_INTERFACE && bmRequestType == 0x01) 
40
        usb_set_interface();
41
42
    else // unsupported request => call to user read request
43
    {
44
        if (!usb_user_read_request(bmRequestType, bRequest))
45
        {
46
            Usb_enable_stall_handshake(EP_CONTROL) ;
47
            Usb_ack_setup_received_free();
48
        }
49
    }
50
}

von Marc (Gast)


Lesenswert?

Ihr diskutiert am Thema vorbei. Ob Betriebssystem, Applikation, Rtos, 
HAL, Treiber, APP, Skript usw ist doch vollkommen egal.

Ziel sollte sein Code zu schreiben, der funktioniert und möglichst 
einige Qualitätskriterien erfüllt. Z.B.visuell schnell verständlich ist, 
damit ein anderer Programmierer (oder man selber) in ein paar Monaten 
Anpassungen machen kann ohne sich ins Knie zu schießen.

Und natürlich gibt es tausend mögliche Lösungen und natürlich kann ich 
mit Goto chaotischen Code erstellen aber vielleicht auch für ein 
spezielles Problem damit übersichtlichen Code erzeugen.


goto bedroom;

von Zeno (Gast)


Lesenswert?

Programmierer schrieb:
> Wie immer, die Lösung ist so extrem simpel:

Wirklich übersichtlicher ist Dein Code nicht. Du verzichtest halt auf 
das goto - das ist alles.

von Zeno (Gast)


Lesenswert?

Marc schrieb:
> Und natürlich gibt es tausend mögliche Lösungen und natürlich kann ich
> mit Goto chaotischen Code erstellen aber vielleicht auch für ein
> spezielles Problem damit übersichtlichen Code erzeugen.

Genau so sehe ich das auch!

von nicht"Gast" (Gast)


Lesenswert?

Clemens M. schrieb:
> void usb_process_request(void)
> {
>   U8 bRequest;
>
>   Usb_reset_endpoint_fifo_access(EP_CONTROL);
>   bmRequestType = Usb_read_endpoint_data(EP_CONTROL, 8);
>   bRequest      = Usb_read_endpoint_data(EP_CONTROL, 8);
>
>   // jede menge komischer Code
> }


Mal ne Frage. Was ist den vbmRequestType und wozu gibt es zwei Variablen 
wenn von der zweiten Variablen anscheinend nur ein Wert vernünftig sein 
kann? Die ganzen magic Numbers im Code machen das Verstehen so ziemlich 
unmöglich. Damit kann man das Ganze ja auch nicht vernünftig 
umschreiben.


Zu dem, jedes Programm auf einem µC ist ein Betriebssystem, Thema...
https://de.wikipedia.org/wiki/Betriebssystem

nope, ists nicht.

PS: Speicher benutzen heißt nicht, ihn zu verwalten.

von Zeno (Gast)


Lesenswert?

nicht"Gast" schrieb:
> Mal ne Frage. Was ist den vbmRequestType und wozu gibt es zwei Variablen
> wenn von der zweiten Variablen anscheinend nur ein Wert vernünftig sein

Also von der 2. Variable gibt es mindestens 11 verschiedene Werte (s. 
Post mit Orginalcode, zähle mal die case durch).

vbmRequestType habe ich nirgendwo gefunden. Du meinst sicher 
bmRequestType. Da es sich hier um ein Codefragment handelt wird's schon 
irgendwo im Quelltext deklariert sein.

@Programmierer: Da siehste es doch schon! Bei Deinem if-Gewurschtel geht 
die Übersicht verloren. Hätte sich "nicht Gast" mal den Orginalquelltext 
angesehen wäre ihm sofort aufgefallen das bRequest mehr als einen 
vernünftigen Wert hat, sofern er das switch/case Konstrukt richtig 
verstanden hat, was ich allerdings bezweifle, wenn ich dies

nicht"Gast" schrieb:
> Die ganzen magic Numbers im Code machen das Verstehen so ziemlich
> unmöglich.

lese. Denn das bedeutet für mich, daß er keine Hexzahlen kennt und 
deshalb den Vergleich der Variable bmRequestType mit selbigen nicht 
versteht.

von Clemens M. (panko)


Lesenswert?

Ich glaube da liegt ein Missverständnis vor: ich habe den Eindruck, dass 
der eine oder andere davon aus geht, dass das was ich gepostet habe für 
mich der Weisheit letzter Schluss ist. Das ist nicht so. Es steht halt 
nur regelmäßig die Frage im Raum, wo goto außerhalb vom Linux Kernel zu 
finden ist. Das ist ein Beispiel.

Ein Programmierer hat auch den Code umgeschrieben. Aber nur formal. Ich 
kann jetzt wirklich nicht sagen, dass ich das übersichtlicher finde. Ist 
Im Grunde doch das Selbe. Müsste jeder zugeben, außer dass man sich 
bemüht hat eben aus Prinzip kein goto zu benutzen. Lesbarer ist es auch 
nicht und die goto Verweigerer müssten eigentlich auch mal sagen, warum 
jetzt die goto Variante schlechter ist - außer dass ein goto enthalten 
ist.

von Clemens M. (panko)


Lesenswert?

Mit "magic number" ist sicherlich nicht hex Notation gemeint, sondern 
die Verwendung von Konstanten, die nicht vom Präprosessor aus Klartext 
erzeugt werden. Sprich jede "magic number" sollte vermutlich in einem 
header stehen. Kann man aber auch wieder sehr gut drüber streiten.

von M. K. (sylaina)


Lesenswert?

Zeno schrieb:
> Es gibt Fälle, wo ein Parameter stehen bleiben muß oder besser sollte,
> …
> Jetzt müßte also jeder der diese DLL
> benutzt seinen Quelltext ändern. Das ist viel zu aufwändig und hier
> dürfte es wohl der bessere Weg sein die Warning zu ignorieren.

Und was spricht dagegen, dass die, die diese DLL benutzen, eine ältere 
Version der DLL benutzen so dass ihre Programme weiterhin funktionieren?
Mal ganz davon ab, z.B. die Youtube-API hat Google auch einfach so mal 
geändert. Es hat Google nicht interessiert, dass jeder sein Programm 
deshalb umschreiben mussten wenn es weiterhin funktionieren sollte. Das 
also dann andere ihre Programme umschreiben müssten ist ein sehr 
schwaches Argument.

von nicht"Gast" (Gast)


Lesenswert?

Zeno schrieb:
> @Programmierer: Da siehste es doch schon! Bei Deinem if-Gewurschtel geht
> die Übersicht verloren. Hätte sich "nicht Gast" mal den Orginalquelltext
> angesehen wäre ihm sofort aufgefallen das bRequest mehr als einen
> vernünftigen Wert hat, sofern er das switch/case Konstrukt richtig
> verstanden hat, was ich allerdings bezweifle, wenn ich dies

Das If gewurschtel habe ich gar nicht gelesen. Ist auch nur gewurschtel.

Warscheinlich habe ich mich nur falsch ausgedrückt. In jedem Request 
wird nur ein RequestType geprüft. Wozu ist der RequestType gut?

Zeno schrieb:
> lese. Denn das bedeutet für mich, daß er keine Hexzahlen kennt und
> deshalb den Vergleich der Variable bmRequestType mit selbigen nicht
> versteht.

Ernsthaft?
Warscheinlich hast du eher keine Ahnung wovon ich schreibe.
https://de.wikipedia.org/wiki/Magische_Zahl_(Informatik)#Magische_Zahlen_in_Code

Wenn er nicht gleich zu dem Absatz springt, dann scroll mal zu Magische 
Zahlen in Code runter.

von Michael S. (rbs_phoenix)


Lesenswert?

Jörg W. schrieb:
> Hast du auch alle 114601 davon einzeln kontrolliert?

Hast du? ;)


Mark B. schrieb:
> Alleine dass etwas benutzt wird, heißt noch nicht dass es so richtig
> ist. Nicht einmal dann, wenn dies häufig geschieht. Häufige Verwendung
> ist keine qualitative Wertung, sondern eine quantitative.

Find ich auch. Gibts eigentlich vergleichbare Statistiken von Windows 
oder MAC OS? Vermutlich nicht, da kein Open Source.


Zeno schrieb:
> Karl hat es auf den Punkt gebracht. Eigentlich sind alle Schleifen und
> Verzweigungen letzendlich GOTO's und wenn man sich den generierten
> Assemblercode anschaut, dann werden solche Sachen i.d.R. in
> Sprunganweisungen umgesetzt  und ob ich nun sage "springe zu A" oder
> "Gehe zu A" ist im Endeffekt das Gleiche.

Was der Compiler daraus macht ist doch egal. Eine Hochsprache ist ja 
hauptsächlich dafür da, den Maschinencode bzw Assemblercode zu 
abstrahieren. Wieso sollte ich dann also so nah wie möglich noch am 
compilierten Maschinencode bleiben?


Es schreibt doch (hoffentlich) keiner eine Schleife so:
1
Schleifenbedingung:
2
3
if(Bedingung_erfüllt){
4
  goto Schleifenbeginn;
5
}
6
goto Schleifenende;
7
8
Schleifenbeginn:
9
// Schleifeninhalt
10
goto Schleifenbedingung;
11
Schleifenende:
, auch wenn das quasi dem compilierten while entspricht. Derjenige 
müsste dann ja (auf 8bitter µC) konsequenter Weise Zahlen vorher in 8bit 
Breite Elemente auftrennen und separat berechnen. Das ist doch irgendwie 
quatsch ;)
Am besten überlässt man es dem Compiler, wo er welchen Maschinenbefehl 
setzt. Er oder Sie wird es am besten wissen.

Zeno schrieb:
> @Programmierer: Da siehste es doch schon! Bei Deinem if-Gewurschtel geht
> die Übersicht verloren.

Ich finde ihn nicht unübersichtlicher. Ich hätte den 2-Zeiler mit "else 
if(bRequest == SET_INTERFACE ..." noch vor den vorherigen "else 
if"-Block gesetzt, damit alle 2-Zeiler untereinander stehen, aber das 
ist auch alles Geschmackssache.
Was ich besser finde ist: der umgeschriebene Code passt auf eine Seite, 
man muss nicht scrollen um alles zu sehen und ist dabei trotzdem noch 
gut lesbar, eingerückt usw. Außerdem hat er nur eine 
Verschachtelungstiefe (if, else if und else). So kann man sich von einer 
Bedingung zur nächsten Hangeln und sieht auf anhieb den einzelnen 
Befehlsaufruf, der ausgeführt wird, sofern die Bedingung erfüllt ist. 
Beim Original sind es 2 Ebenen. D.h. wenn der Cursor in die Mitte 
positioniert wird, weil da z.B. ein Suchergebnis ist (man sucht z.B. 
nach "usb_set_address();" ) und man will nun wissen, wann der aufgerufen 
wird, muss erstmal hochgescrollt werden, um zu wissen, welche Variable 
denn im Switch() steht, wieder runter scrollen um die nächste Bedingung 
zu sehen und dann nochmal runter scrollen, um zu gucken, wann denn die 
Sprungmarke kommt (wärend man hofft in die richtige Richtung zu 
scrollen), zu der gesprungen wird, sollte die Bedingung nicht true sein. 
Hier könnte man die Suche erleichtern, in dem man die Sprungmarke nach 
ganz links setzt, wie auch in ASM, im Beispiel aber nicht der Fall.

Aber nochmal: Das ist alles Geschmackssache, weshalb es keine richtige 
und falsche Meinung gibt. Und ich halte mich auch nicht für einen 
unfehlbaren Programmierer (zumal das nicht mein Hauptjob ist) der 
behaupten könnte, dass ein goto in keinem Fall angebracht ist (wo glaube 
ich bisher jeder zugestimmt hat). Ich für meinen Teil hatte bisher aber 
noch nie den Fall, wo ICH ein goto für die bessere Wahl gehalten habe.
BTW: MSDN z.B. schreibt:
> It is good programming style to use the break, continue, and return statements
> instead of the goto statement whenever possible. However, because the break
> statement exits from only one level of a loop, you might have to use a goto
> statement to exit a deeply nested loop.
Das wäre wohl so ein Fall


M. K. schrieb:
> Und was spricht dagegen, dass die, die diese DLL benutzen, eine ältere
> Version der DLL benutzen so dass ihre Programme weiterhin funktionieren?

Dann würden die aber nicht mehr eine Berechnung nach (aktueller) ISO 
haben.


M. K. schrieb:
> Das also dann andere ihre Programme umschreiben müssten ist ein sehr
> schwaches Argument.

Naja.. Die Funktion wird eh geändert. Und die Parameter drin zu lassen 
und vlt ein (void)var zu spendieren ist bei weitem nicht so Aufwendig, 
Zeitintensiv (vielleicht 10 Sekunden) und somit teuer, wie alle zu 
benachrichtigen, die sich dann auch nochmal dransetzen müssen, alle 
Dateien durchsuchen müssen und dann umschreiben, neu Kompilieren und ggf 
testen oder auf Messplätze aufspielen (vielleicht 1-2 Tage PRO 
Entwickler). Hier macht das für mich schon Sinn.

Anders ist es natürlich, wenn einen die anderen Programmierer nicht die 
Bohne jucken. Dann kann man eben sagen: Ändert eure Programme. Hier 
finde ich ja die optionalen Parameter super. So laufen noch alte 
Programme aber neue müssen keinen Dummy-Parameter eingeben.

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


Lesenswert?

nicht"Gast" schrieb:
> Warscheinlich habe ich mich nur falsch ausgedrückt. In jedem Request
> wird nur ein RequestType geprüft. Wozu ist der RequestType gut?

Lies dir die USB spec durch, dann weißt du, warum es da zwei
verschiedene Dinge gibt.

Ich habe sowas auch schon runtergerattert (siehe µracoli-Projekt),
in diesem Falle ohne “goto”.  Allerdings habe ich dort die
Fehlerbehandlung beim Aufrufer gemacht und dafür jede Menge
premature return im Code, die es natürlich nach der „reinen Lehre“
genauso wenig geben dürfte.  Ist bloß 'ne andere Art “goto”.

Nennenswert übersichtlicher ist weder das eine noch das andere und
auch nicht das obige if/else-Gewurschtel.

von Zeno (Gast)


Lesenswert?

nicht"Gast" schrieb:
> Wozu ist der RequestType gut?

Keine Ahnung, da müßte man den kompletten Code sehen. Das gepostete ist 
ja nur ein Auszug.

von Zeno (Gast)


Lesenswert?

nicht"Gast" schrieb:
> Ernsthaft?
> Warscheinlich hast du eher keine Ahnung wovon ich schreibe.
> https://de.wikipedia.org/wiki/Magische_Zahl_(Informatik)#Magische_Zahlen_in_Code

So wie Du Dich ausgedrückt hast mußte ich davon ausgehen, daß Du nicht 
mit Hex-Zahlen kannst.
Auch wenn in der von Dir zitierten Quelle von schlechten Stil gesprochen 
wird, so empfinde ich das noch lange nicht so. Klar kann ich das auch in 
einem Konstantenausdruck hinterlegen, aber dann brauch ich die passende 
"Tabelle" um zu verstehen was da passiert.
Also ich habe mit "Magic Numbers" kein Problem.

von Zeno (Gast)


Lesenswert?

Michael S. schrieb:
> umgeschriebene Code passt auf eine Seite

Das ist ein ganz schlechtes Argument gegen GOTO, 1 - 2 Statements mehr 
und der Code paßt nicht mehr auf eine Seite.

von Zeno (Gast)


Lesenswert?

Michael S. schrieb:
> M. K. schrieb:
>> Und was spricht dagegen, dass die, die diese DLL benutzen, eine ältere
>> Version der DLL benutzen so dass ihre Programme weiterhin funktionieren?
>
> Dann würden die aber nicht mehr eine Berechnung nach (aktueller) ISO
> haben.

Richtig erkannt!

von nicht"Gast" (Gast)


Lesenswert?

Zeno schrieb:
> Also ich habe mit "Magic Numbers" kein Problem.

Wenn man nach dem Motto "Nach mir die Sinnflut" programmiert, dann kann 
man natürlich beliebiges machen. Dann kannst du auch gerne mit gotos um 
dich werfen, bis du selber nicht mehr druchblickst.

Genau darum geht es aber hier. Nachvollziehbarkeit von Quellcode. Nur 
aus diesen Grund ist goto bei den Meisten verpönt. Technische Gründe hat 
das keinen. Aber das haben die Paradigmen in der Programmierung nun mal 
gemein.

von M. K. (sylaina)


Lesenswert?

Michael S. schrieb:
> Dann würden die aber nicht mehr eine Berechnung nach (aktueller) ISO
> haben.

Sie sind also sowieso gezwungen ihr Programm zu ändern...

von Zeno (Gast)


Lesenswert?

Michael S. schrieb:
> Hier
> finde ich ja die optionalen Parameter super.

Kann C leider nicht wirklich gut. Bin auch ein großer Freund optionaler 
Parameter. Macht das Programmieren leichter, wenn man im Nachgang was 
ändern kann ohne alle Funktionsaufrufe anpassen zu müssen.

von Zeno (Gast)


Lesenswert?

nicht"Gast" schrieb:
> Wenn man nach dem Motto "Nach mir die Sinnflut" programmiert

Was  bitte ist der Unterschied zwischen
1
a = b & 0x02;
und
1
#define igend_etwas   0x02
2
3
....
4
5
a = b & irgend_etwas;
6
....

Wenn ich die #define-Zeile nicht sehe dann ist die Gleichung nicht 
besser lesbar, bloß weil ich eine Konstante hinschreibe. Im Gegenteil! 
Im ersten Beispiel sehe ich sofort das b mit 2 ver"und"et wird und a 
ergibt. Im zweiten Beispiel muß ich mir den Konstantenparameter über das 
#define erst erschließen, aber da weis ich trotzdem nicht wozu das gut 
ist. Wenn man's ganz sauber macht gehört dann ein Kommentar dazu 
entweder zum #define oder zur Gleichung.

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


Lesenswert?

Zeno schrieb:
> Im Gegenteil! Im ersten Beispiel sehe ich sofort das b mit 2 ver"und"et
> wird und a ergibt.

Allerdings interessiert dich normalerweise beim Lesen nicht, welches
Bit da nun genau erfragt wird.  Vergleiche mal obigen Code mit dem
hier:
1
    case GET_CONFIGURATION:
2
        if (bmRequestType == (DIR_IN | RQTYPE_STANDARD | RQRCPT_DEVICE))
3
        {
4
            UEINTX &= ~_BV(RXSTPI);
5
            get_configuration();
6
            break;
7
        }
8
        return false;
9
10
    case GET_DESCRIPTOR:
11
        if (bmRequestType == (DIR_IN | RQTYPE_STANDARD | RQRCPT_DEVICE))
12
        {
13
            /* descriptor type */
14
            switch (wValue >> 8)
15
            {
16
            case DEVICE_DESC:
17
                if (wIndex == 0)
18
                {
19
                    UEINTX &= ~_BV(RXSTPI);
20
                    get_flash_descriptor((const char *)&device_desc,
21
                                         sizeof(device_desc), wLength);
22
                    break;
23
                }
24
                return false;
25
26
            case CONFIGURATION_DESC:
27
                if (wIndex == 0)
28
                {
29
                    UEINTX &= ~_BV(RXSTPI);
30
                    get_flash_descriptor((const char *)&configuration_desc,
31
                                         sizeof(configuration_desc), wLength);
32
                    break;
33
                }
34
                return false;
35
36
            case STRING_DESC:
37
                /* descriptor index */
38
                switch (wValue & 0xFF)
39
                {
40
                    uint8_t len;
41
42
                case 0:
43
                    UEINTX &= ~_BV(RXSTPI);
44
45
                    /* .bLength of actual descriptor */
46
                    len = pgm_read_byte(&string_descriptor_langs);
47
                    get_flash_descriptor((const char *)&string_descriptor_langs,
48
                                         len, wLength);
49
                    break;

Ich denke, selbst ohne Kenntnis des USB-Standards kannst du aus dem
Code mit „benamsten“ Konstanten besser erkennen, was da gerade
erfragt wird, und wie dann die Antwort zustande kommt.

p.s.: Ich bin gewiss kein Freund der „Ungarischen Notation“.  Die
Namen der Variablen mit ihrem „bXXX“, „bmXXX“ oder „wXXX“ entsprechen
einfach 1:1 den Feldnamen, die im USB-Standard so stehen.  Das
erleichtert es einem Uneingeweihten, sich bei Bedarf schnell darin
zurechtzufinden, indem er sich eben den Standard danebenlegt.

: Bearbeitet durch Moderator
von Ralf G. (ralg)


Lesenswert?

Zeno schrieb:
> Im zweiten Beispiel muß ich mir den Konstantenparameter über das
> #define erst erschließen, aber da weis ich trotzdem nicht wozu das gut
> ist.
Fast immer interessiert die konkrete Zahl überhaupt nicht. Das ist ein 
Flag, eine Pin-Nummer,... Du durchsuchst jedesmal dein ganzes Projekt, 
um aus 0x02 ein 0x04 zu machen?

> Wenn man's ganz sauber macht gehört dann ein Kommentar dazu
> entweder zum #define oder zur Gleichung.
Steht doch sogar in deinem Beispiel da: 'irgend_etwas'. Reicht!

von Mark B. (markbrandis)


Lesenswert?

Zeno schrieb:
> nicht"Gast" schrieb:
>> Wenn man nach dem Motto "Nach mir die Sinnflut" programmiert
>
> Was  bitte ist der Unterschied zwischen
>
1
a = b & 0x02;
> und
1
#define igend_etwas   0x02
2
> 
3
> ....
4
> 
5
> a = b & irgend_etwas;
6
> ....

Zwei Dinge:

1.) Man kann und sollte die Konstante so benennen, dass aus dem Namen 
ersichtlich wird wozu sie gut ist. Das macht das Verständnis des Codes 
einfacher.

2.) Sollte sich der Zahlenwert mal ändern, dann passt man ihn an genau 
EINER Stelle an. Und nicht an fünfzig.

von nicht"Gast" (Gast)


Lesenswert?

Och menno,

da geht man einmal zum Essen und vormuliert eine gesalzene Antwort und 
dann haben das schon drei Leute vorneweg genommen^^


PS: Wer Magic Numbers schon verteidigt (und bei denen ist sich die 
Community eigentlich einig), der hat sich für eine Diskusion über goto 
IMHO disqualifiziert.

von Mark B. (markbrandis)


Lesenswert?

nicht"Gast" schrieb:
> PS: Wer Magic Numbers schon verteidigt (und bei denen ist sich die
> Community eigentlich einig), der hat sich für eine Diskusion über goto
> IMHO disqualifiziert.

Sehe ich auch so.

von Clemens M. (panko)


Lesenswert?

Ich glaube da brauchen wir nicht vom Threadthema abweichen.
Die allermeisten werden sich einig sein, dass wichtige Konstanten in 
menschenlesbarer Form sinnvoll sind. Und doch, es stimmt, man kann da 
drüber streiten.

Dennoch möchte ich bitten einfach mal zu sagen, warum genau in dem 
usb-Beispiel jetzt goto schlecht ist. Religiöse Gründe mal außen vor.
Viele wie Jörg haben da eine gesundere Haltung.

von Michael S. (rbs_phoenix)


Lesenswert?

Jörg W. schrieb:
> Allerdings habe ich dort die
> Fehlerbehandlung beim Aufrufer gemacht und dafür jede Menge
> premature return im Code, die es natürlich nach der „reinen Lehre“
> genauso wenig geben dürfte.  Ist bloß 'ne andere Art “goto”.

Finde ich nicht. Vom resultierenden Maschinencode mag das sein, doch bei 
einem return weiß ich und jeder andere automatisch, dass die aktuelle 
Funktion verlassen wird und vorallem, welchen Wert die Funktion zurück 
gibt. Bei einem goto weißt man beides nicht.


Zeno schrieb:
> Michael S. schrieb:
>> umgeschriebene Code passt auf eine Seite
>
> Das ist ein ganz schlechtes Argument gegen GOTO, 1 - 2 Statements mehr
> und der Code paßt nicht mehr auf eine Seite.

Es soll garkein Argument GEGEN goto sein. Es soll nur heißen, dass der 
funktionell gleiche, aber umgeschriebene Code kürzer ist. Bei mehr 
Unterscheidungen von bRequest wird der Unterschied der Zeilenanzahl 
immer größer. Und mir gefällt das schlankere eben besser, weil dort bis 
zu einem gewissen Grad noch alles auf eine Seite passt, wo es beim 
anderen nicht mehr passt. Ich schreibe auch das "{" immer hinter das 
if/while/... um eine Zeile zu sparen, weil ich es nicht weniger 
übersichtlich finde. So können aus 1000 Zeilen Code auch mal schnell 900 
werden, nur wenn man für das { keine eigene Zeile verwendet.
Der Unterschied in diesem Fall (mit dem "{" hinterm if) wäre 50 Zeilen 
weniger. 50 Zeilen, die also gespart werden können, ohne die eigentliche 
Funktion zu beeinflussen und (aus meiner Sicht) ohne dass die 
Übersichtlichkeit drunter leidet. Es geht mir hier also nicht um goto 
oder nicht, sondern um die Kompaktheit vom Code.


M. K. schrieb:
> Michael S. schrieb:
>> Dann würden die aber nicht mehr eine Berechnung nach (aktueller) ISO
>> haben.
>
> Sie sind also sowieso gezwungen ihr Programm zu ändern...

Wieso das? Ein Programm läd die DLL, erfasst die Parameter, wirft die 
Funktion aus der DLL an und zeigt das Ergebnis an oder sendet es zu 
irgendeiner Art Protokollierung. Ändert sich diese Berechnung, ändert 
sich die DLL, die geladen wird. Bei gleichen Funktionsnamen und gleichen 
Parametern juckt das aber das Programm nicht. Man könnte höchstens 
Argumentieren, dass es einen Mehraufwand gibt, einen Parameter zu 
erfassen (Endtemperatur), der garnicht mehr begraucht wird. Sollte die 
Messung aber parallel zu irgendwas laufen oder einfach Zeitlich kaum was 
ausmachen, kann das eben vernachlässigt werden und bleibt drin. Dann 
muss das eigentliche Programm bzw die Programme nicht geändert werden.


Zeno schrieb:
> Kann C leider nicht wirklich gut. Bin auch ein großer Freund optionaler
> Parameter. Macht das Programmieren leichter, wenn man im Nachgang was
> ändern kann ohne alle Funktionsaufrufe anpassen zu müssen.

Meine ersten Programmiererfahrungen habe ich mit PHP gemacht, vor 
Ewigkeiten. Da geht das auch, sogar ohne festgelegtem Datentyp. Man 
konnte also einem Parameter, der für eine Zahl bestimmt war, den 
Standardwert "FALSE" geben und in der Funktion mit is_numeric() prüfen, 
ob es eine Zahl ist, also ob er (richtig) angegeben wurde oder nicht.

von Mark B. (markbrandis)


Lesenswert?

Clemens M. schrieb:
> Dennoch möchte ich bitten einfach mal zu sagen, warum genau in dem
> usb-Beispiel jetzt goto schlecht ist. Religiöse Gründe mal außen vor.
> Viele wie Jörg haben da eine gesundere Haltung.

Die Inkonsistenz finde ich nicht gut. In den if-Pfaden wird jeweils eine 
Funktion aufgerufen, in den else-Pfaden wird jeweils per goto 
gesprungen. Wozu dieser Unterschied? Warum nicht einheitlich?

Ja, immer mit goto wäre dann auch einheitlich ;-)
Aber immer mit Funktionsaufrufen fände ich einfach besser.

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

@Clemens M. (panko)

>Dennoch möchte ich bitten einfach mal zu sagen, warum genau in dem
>usb-Beispiel jetzt goto schlecht ist.

Es ist überflüssig, wenn gleich in diesem Fall nicht ultimativ schlecht.

Hier meine Variante ;-)
1
void usb_process_request(void)
2
{
3
  U8 bRequest;
4
5
  Usb_reset_endpoint_fifo_access(EP_CONTROL);
6
  bmRequestType = Usb_read_endpoint_data(EP_CONTROL, 8);
7
  bRequest      = Usb_read_endpoint_data(EP_CONTROL, 8);
8
  U8 unsupported = 1;
9
10
  switch (bRequest)
11
  {
12
  case GET_DESCRIPTOR:
13
    if (bmRequestType == 0x80) {
14
      usb_get_descriptor();
15
      unsupported = 0;
16
    }
17
    break;
18
19
  case GET_CONFIGURATION:
20
    if (bmRequestType == 0x80) {
21
      usb_get_configuration();
22
      unsupported = 0;
23
    }
24
    break;
25
26
  case SET_ADDRESS:
27
    if (bmRequestType == 0x00) {
28
      usb_set_address();
29
      unsupported = 0;
30
    }
31
    break;
32
33
  case SET_CONFIGURATION:
34
    if (bmRequestType == 0x00) {
35
      usb_set_configuration();
36
      unsupported = 0;
37
    }
38
    break;
39
40
  case CLEAR_FEATURE:
41
    if (bmRequestType <= 0x02) {
42
      usb_clear_feature();
43
      unsupported = 0;
44
    }
45
    break;
46
47
  case SET_FEATURE:
48
    if (bmRequestType <= 0x02) {
49
      usb_set_feature();
50
      unsupported = 0;
51
    }
52
    break;
53
54
  case GET_STATUS:
55
    if (0x7F < bmRequestType && bmRequestType <= 0x82) {
56
      usb_get_status();
57
      unsupported = 0;
58
    }
59
    break;
60
61
  case GET_INTERFACE:
62
    if (bmRequestType == 0x81)
63
    {
64
      if(!usb_get_interface())
65
      {
66
        Usb_enable_stall_handshake(EP_CONTROL);
67
        Usb_ack_setup_received_free();
68
      }
69
      unsupported = 0; 
70
    }
71
    break;
72
73
  case SET_INTERFACE:
74
    if (bmRequestType == 0x01) {
75
      usb_set_interface();
76
      unsupported = 0;
77
    }
78
    break;
79
80
  case SET_DESCRIPTOR:
81
  case SYNCH_FRAME:
82
  default:
83
    break;
84
  }
85
86
  // unsupported request => call to user read request
87
  if (unsupported) {
88
    if (!usb_user_read_request(bmRequestType, bRequest))
89
    {
90
      Usb_enable_stall_handshake(EP_CONTROL) ;
91
      Usb_ack_setup_received_free();
92
    }
93
  }
94
}

von Ralf G. (ralg)


Lesenswert?

Je öfter ich darüberschaue, finde ich das Beispiel sogar immer besser:
Beitrag "Re: goto verpönnt - was dann nehmen?"

- Die gesamte Funktionalität ist innerhalb der 'switch'-Anweisung
- Wenn man den 'default'-Zweig (und dann sicher auch die beiden anderen 
Konstanten) über ein gesetztes Flag außerhalb 'behandelt', meckert der 
Compiler, dass möglicherweise nicht alle Fälle abgedeckt sind. So 
bekommt man gleich noch die Warnung weg.

von Mark B. (markbrandis)


Lesenswert?

Ralf G. schrieb:
> - Wenn man den 'default'-Zweig (und dann sicher auch die beiden anderen
> Konstanten) über ein gesetztes Flag außerhalb 'behandelt', meckert der
> Compiler, dass möglicherweise nicht alle Fälle abgedeckt sind. So
> bekommt man gleich noch die Warnung weg.

Jedes switch hat auch einen default, wenn man richtig programmiert. Wo 
soll da eine Warnung herkommen?

von Ralf G. (ralg)


Lesenswert?

Mark B. schrieb:
> Jedes switch hat auch einen default, wenn man richtig programmiert. Wo
> soll da eine Warnung herkommen?

So steht wenigstens noch was drin :-)

von Michael S. (rbs_phoenix)


Lesenswert?

Clemens M. schrieb:
> Dennoch möchte ich bitten einfach mal zu sagen, warum genau in dem
> usb-Beispiel jetzt goto schlecht ist. Religiöse Gründe mal außen vor.
> Viele wie Jörg haben da eine gesundere Haltung.

Funktionell ist beides gleich. Daher kann man nicht sagen, dass die 
"goto-Variante" schlechter/schlecht ist. Höchstens schlechter zu lesen, 
zu verstehen oder nicht der allgemeinen Empfehlung entsprechend oder 
keine Ahnung was noch. Aber das ist subjektiv.
Wenn ich es schlechter zu lesen finde, musst du das ja nicht auch so 
sehen.

Mich würde mal interessieren, was an der umgeschriebenen Form "schlecht" 
ist. Funktionell ist es ja identisch. Ich vermute, dass es viele nicht 
so übersichtlich finden, so wie ich. Da sieht man mal wieder, dass es 
Geschmackssache ist.

von Ralf G. (ralg)


Lesenswert?

Ralf G. schrieb:
> So steht wenigstens noch was drin :-)

Falk B. schrieb:
1
  case SET_DESCRIPTOR:
2
  case SYNCH_FRAME:
3
  default:
4
    break;
Das sieht immer so unfertig aus: Erstmal die Konstanten hinschreiben, 
damit der Compiler zufrieden ist. Die zugehörige Funktionalität kommt in 
der Testphase nach und nach dazu. Allerdings: Ich hätte es genauso 
gemacht! Aber:

Ralf G. schrieb:
> Je öfter ich darüberschaue, finde ich das Beispiel sogar immer besser:

: Bearbeitet durch User
von nicht"Gast" (Gast)


Lesenswert?

Ralf G. schrieb:
> Das sieht immer so unfertig aus: Erstmal die Konstanten hinschreiben,
> damit der Compiler zufrieden ist. Die zugehörige Funktionalität kommt in
> der Testphase nach und nach dazu. Allerdings: Ich hätte es genauso
> gemacht!

Ja, das mache ich auch gerne so. Nur kann man da auch mal schnell die 
implementation eines cases vergessen.

OT: da lob ich mir in C# meine lieblings Exception 
(NotImplementedException ^^)

von Clemens M. (panko)


Lesenswert?

Dass man goto seltenst wirklich braucht ist sicher richtig.

Dass es allerdings auch nicht (wie öfter angedeutet oder explizit 
gesagt) einem idiotischen Programmierer entspringt ebenso.

Dass es unterschiedliche Vorlieben gibt kann keiner bestreiten und dass 
ganz konkret bei dem if-Grab und der goto Lösung keine messbare Aussage 
über die Lesbarkeit getroffen werden kann entspricht der Subjektivität.

Falk hat jetzt noch eine Lösung gepostet. Die mit Flag. Die ist 
natürlich naheliegend und auch deutlich besser lesbar als das if Ding. 
(da ist für mich persönlich die Formatierung durch den switch erheblich 
weiter vorne) Weil die so naheliegt hatte ich die oben 'indiziert'.

Es ist sogar denkbar, dass man Vorlieben im Laufe der Jahre ändert. 
Stelle ich jedenfalls hin und wieder fest.
Ich finde einfach, dass es nie gut ist sich selber einem Dogma zu 
unterwerfen und nicht offen und flexibel zu sein. Selbst die Leute die 
gegen eine goto-Verwendung argumentieren müssen ja zugeben, dass sehr 
oft nichts wirklich objektives dagegen spricht.

Ganz schlecht ist es wenn jemand nur blind Phrasen zitiert die er mal 
gehört oder gelesen hat ohne sich selber eine Meinung zu bilden. Und da 
läd die goto Debatte unschöner Weise zu ein.
Einfach die Aussage eines Professors (die dieser vermutlich auch 
unreflektiert zitiert) lebenslang als gottgegeben hinzunehmen ist halt 
unnötig.


Tjoar eigenltich ist alles gesagt, oder? Kann, aber lässt sich idR 
vermeiden. Schadet aber auch nicht. Ist Geschmackssache.

von nicht"Gast" (Gast)


Lesenswert?

Ach, vergessen.

das Problem an der einen Funktion (die aus der ASF) ist, dass sie 
eingebettet ist.

Ich hätte erst das komplette SetupPaket in ein struct eingelesen und 
erst dann and die einzelnen Funktionen übergeben.

dann sieht das ganze eher so aus:
1
struct setupPacket readPacket // blablabla initialisieren, einlesens u.s.w
2
3
case SET_INTERFACE:    
4
    usb_set_interface(&readPacket);    
5
    break;

dann ist das alles schon vom Stack gelesen und braucht keine 
Resteleserampe (wenn ich das richtig verstanden habe).

http://www.beyondlogic.org/usbnutshell/usb6.shtml

von M. K. (sylaina)


Lesenswert?

Michael S. schrieb:
> Wieso das?

Weil deren Programm sonst weiterhin suggerieren wird, dass die 
Temperatur noch eine Rolle spielt.

von Zeno (Gast)


Lesenswert?

Jörg W. schrieb:
> Ich denke, selbst ohne Kenntnis des USB-Standards kannst du aus dem
> Code mit „benamsten“ Konstanten besser erkennen, was da gerade
> erfragt wird, und wie dann die Antwort zustande kommt.

Also erst mal sagen mir die benamsten Konstanten gar nichts und ich 
erkenne nur das da da gegen irgend einen Wert verglichen wird.

Jörg W. schrieb:
> Ich bin gewiss kein Freund der „Ungarischen Notation“.  Die
> Namen der Variablen mit ihrem „bXXX“, „bmXXX“ oder „wXXX“ entsprechen
> einfach 1:1 den Feldnamen, die im USB-Standard so stehen.

Erst mit dem Wissen um den USB-Standard wird ein richtiger Schuh daraus. 
Ich mußte mich bisher noch nicht damit befassen und kenne diesen deshalb 
nicht.
Mit
1
b & 0x02
 hingegen sehe ich sofort, das an dieser Stelle die Variable b auf Bit1 
abgeprüft wird.

Das heißt jetzt nicht das ich was gegen benamte Konstanten habe und bei 
allgemeinen Standards machen diesen ja auch Sinn, aber wenn ich in einem 
kleinen Programm auf ein bestimmtes Bit abprüfen will, dann schreibe ich 
das in der Regel hin und zwar so wie oben beschrieben.

Zeno

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


Lesenswert?

Zeno schrieb:
> Mit b & 0x02 hingegen sehe ich sofort, das an dieser Stelle die Variable
> b auf Bit1 abgeprüft wird.

Das Wissen hilft dir aber rein gar nichts.  Davon weißt du nicht,
ob das nun eine Anforderung an das Gerät, an die Klasse oder was
auch immer ist.  Das müsstest du dann immer erst im Standard
nachlesen, während man es sich mit den Namen irgendwann merken kann,
was da so ungefähr läuft.

Aber lassen wir das, schreib' deine magischen Zahlen einfach weiter,
der Rest der Welt wird es eher nicht so haben wollen, und wir müssen
uns ja in deinen Code zum Glück nicht reinfinden.

von Zeno (Gast)


Lesenswert?

Michael S. schrieb:
> Bei gleichen Funktionsnamen und gleichen
> Parametern juckt das aber das Programm nicht. Man könnte höchstens
> Argumentieren, dass es einen Mehraufwand gibt, einen Parameter zu
> erfassen (Endtemperatur), der garnicht mehr begraucht wird.

Genauso ist! Im übrigen wird (muß) um bei diesem Beispiel zu bleiben die 
Endtemperatur weiterhin erfaßt werden, da sie dokumentiert werden muß. 
Sie geht eben nur nicht mehr in die Berechnung ein. Wird zwar für manche 
keinen Sinn machen, aber die DakkS-Richtlinien schreiben das so vor und 
da wir ein akkrediertes Unternehmen sind, müssen wir uns an die 
Richtlinien halten.


Zeno

von Zeno (Gast)


Lesenswert?

Mark B. schrieb:
> nicht"Gast" schrieb:
>> PS: Wer Magic Numbers schon verteidigt (und bei denen ist sich die
>> Community eigentlich einig), der hat sich für eine Diskusion über goto
>> IMHO disqualifiziert.
>
> Sehe ich auch so.

Ihr seid schon 2 ganz schlaue. Ich deklariere wegen 2 3 Abfragen benamte 
Konstanten, ich glaube es hackt. Da schreibe ich den Wert hin und 
fertig. Das bedeutet ja nicht das man das generell so macht.

Keine magic Numbers zu benutzen ist genau so engstirnig wie GOTO 
generell zu verteufeln.

Zeno

von M. K. (sylaina)


Lesenswert?

Zeno schrieb:
> das an dieser Stelle die Variable b auf Bit1
> abgeprüft wird.

Ja, aber da weißt du nicht warum das geprüft wird.

So ein Vergleich:

Prüfe Register 3, bit 4 ob es gesetzt ist und setze dann Register 2, bit 
1 wäre doch sehr verwirrend. Besser wäre da doch

Prüfe ob an PortB der Taster A gedrückt ist und schalte dann an PortA 
LED A ein.

Das wäre doch viel besser. Und genau sowas sollen doch benamte 
Konstanten ermöglichen. Ist mir zumindest auch immer lieber als 
irgendwelche Zahlenwerte ohne Bezug zu dem was sie repräsentieren.

von Zeno (Gast)


Lesenswert?

M. K. schrieb:
> Das wäre doch viel besser. Und genau sowas sollen doch benamte
> Konstanten ermöglichen. Ist mir zumindest auch immer lieber als
> irgendwelche Zahlenwerte ohne Bezug zu dem was sie repräsentieren.

Bestreite ich doch gar nicht und wenn man dann noch zu den Namen einen 
Bezug herstellen kann ist doch alles chick.

Benamte Konstanten müssen aber deklariert sein um sie benutzen zu 
können. Das tue ich entweder mit #define oder ich benötige die 
Headerdatei wo die Konstante deklariert ist. In einem (sehr) kleinen 
Projekt werde ich weder eine Headerdatei einbinden deren Länge das 
eigentliche Projekt um ein vielfaches übersteigt noch werde ich eine 
Konstante deklarieren, wenn ich diesen Wert nur an 1 - 2 Stellen 
benötige. Da die meisten meiner Projekte privater Natur sind muß ich 
mich an keine Dogmen binden - da muß nur ich den Code verstehen.
Wenn man was im Team macht ist das durchaus was anderes und dann hält 
man sich an allgemeinen Regeln bzw. an die vom Team aufgestellten 
Regeln.

von Karl Käfer (Gast)


Lesenswert?

Michael S. schrieb:
> M. K. schrieb:
>> Ich sehe da nicht, dass ich schrieb man solle Fehler nicht beseitigen.
>> Hab vielleicht was auf der Brille.
>
> Wenn du
> also sagst, der Unterschied zwischen Fehlern und Warnungen ist, dass
> eine Warnung beseitigt werden soll, heißt es im Umkehrschluss, ein
> Fehler soll nicht beseitigt werden. Sonst wäre es kein Unterschied. Ich
> glaub aber auch, dass jeder weiß, dass du das so nicht gemeint hast,
> sondern nur sagen wolltest, dass Warnungen im allgemeinen beseitigt
> werden sollen, Fehler natürlich ebenso.

Wenn wir hier schon beim Korinthenkacken sind, dann bitte wenigstens 
richtig: Fehler sollen nämlich nicht beseitigt werden, sondern Fehler 
müssen beseitigt werden. Das unterscheidet sie von Warnungen, die nur 
beseitigt werden sollen, aber nicht müssen.

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


Lesenswert?

Zeno schrieb:
> In einem (sehr) kleinen Projekt werde ich weder eine Headerdatei
> einbinden deren Länge das eigentliche Projekt um ein vielfaches
> übersteigt

Dann wirst du aber nie einen AVR programmieren dürfen.  Selbst bei
einem ATmega328P ist die Headerdatei für den Controller schon knapp
1000 Zeilen lang.  Nach deiner Anforderung dürftest du folglich damit
kein Projekt von weniger als vielleicht 500 Zeilen anfangen …

von Clemens M. (panko)


Lesenswert?

Um mal Zenos Punkt zu stützen kann man auch wieder relativieren. Wie 
immer im Leben.
1
uint32_t timeout = tick_ms + 100;
2
while( tick_ms < timeout) {
3
(...)
4
}
5
6
gegen
7
#define TIMEOUT_MS 100
8
9
uint32_t timeout = tick_ms + TIMEOUT_MS;
10
while( tick_ms < timeout) {
11
(...)
12
}

Das kann auch in einem Header schnell unübersichtlich werden, wenn man 
wirklich wieder ALLE numerischen Konstanten blind ersetzt.
kann schließlich so was werden:
1
#define TIMEOUT_UART_RX_MS 100
2
#define TIMEOUT_UART_TX_MS 100
3
#define TIMEOUT_USER_ENRY
4
#define TIMEOUT_BLA
5
#define TIMEOUT_BLUB
6
(....)

Würde ich im konkreten Fall entscheiden ob das jetzt Sinn macht. Ein 
Dritter muss ja auch erst wissen, wo Timeouts abgefragt werden und falls 
das nur einmalig ist wird der Header unübersichtlicher.

Aber was wieder unstreitbar ist, das ist die Tatsache, dass die nackte 
Konstante 100 hier nicht mystisch ist.

von chris_ (Gast)


Lesenswert?

Da der Thread immer länger wird, kennt Ihr den schon:
Beitrag ""goto"-Befehl in C"

von Yalu X. (yalu) (Moderator)


Lesenswert?

Jörg W. schrieb:
> Ich habe sowas auch schon runtergerattert (siehe µracoli-Projekt),
> in diesem Falle ohne “goto”.

Bei diesem Projektnamen hätte ich eigentlich genau das Gegenteil,
nämlich ganz viele Gotos erwartet:

  https://www.miracoli.de/

SCNR

von nichtCler (Gast)


Lesenswert?

chris_ schrieb:
> Da der Thread immer länger wird, kennt Ihr den schon:
> Beitrag ""goto"-Befehl in C"

Astrein. Keine Front hat sich verändert :) Goto ohne Tabs? Warum gehen 
nicht einfach alle nach Hause? Fragen ihren Chef oder tun einfach statt 
zu fabulieren.

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


Lesenswert?

Yalu X. schrieb:
> Bei diesem Projektnamen hätte ich eigentlich genau das Gegenteil,
> nämlich ganz viele Gotos erwartet:
>
>   https://www.miracoli.de/

Tja, Namen sind halt Schall und Rauch. :-)

Nein, Axel hatte damals schon etwas recherchiert, nicht dass die
sich davon angep***t fühlen, aber das ist wohl erstens weit genug
weg von Nudeln, und zweitens ist „Miracoli“ ein ganz normales
italienisches Wort (bzw. ein Kasus dessen).

von W.S. (Gast)


Lesenswert?

Mark B. schrieb:
> Warum diese Eigenheit der Programmiersprache C für die Verwendung von
> goto sprechen soll, erschließt sich mir nicht so recht.

Ähem.. nun ja, es liegt wohl an deinem etwas zu engen Horizont.
Siehe Adenauer:
"Wir leben alle unter dem gleichen Himmel, aber wir haben nicht alle den 
gleichen Horizont."

Ich hatte die sachliche Begründung ja schon geschrieben, also lies 
gründlicher.

W.S.

von W.S. (Gast)


Lesenswert?

Michael S. schrieb:
>> It is good programming style to use the break, continue, and return statements
>> instead of the goto statement whenever possible.

OK Michael, das war ein Zitat und nicht von dir, nun ja.

Aber "whenever possible" ???

Das ist ne Unverschämtheit.

Da will mir ( MIR!! ) irgend jemand vorschreiben, was guter 
Programmierstil ist. Und das soll sich darin ausdrücken, daß man alles 
andere außer goto zu verwenden hat "whenever possible"? Dreistigkeit 
sowas! Frechheit!

Nein, Zitate von solcher Machart braucht die Welt nicht.

W.S.

von W.S. (Gast)


Lesenswert?

Jörg W. schrieb:
> if (bmRequestType == (DIR_IN | RQTYPE_STANDARD | RQRCPT_DEVICE))
>         {
>             UEINTX &= ~_BV(RXSTPI);

Jörg, du willst sicherlich nicht behaupten, daß dieses Zitat lesbarer 
sei als wenn dort mit schnöden (1<<xyz) gearbeitet worden wäre und 
hinter dem Statement ein erhellender Kommentar stünde.
Also (ohne Anspruch auf Richtigkeit) etwa so:
  UEINTX &= ~(1<<7);  // reset für TX ein

Mir ist es elleweil ein Graus, wenn Programmierer in ihrem Bestreben, 
sich besonders bedeutungsvoll auszudrücken, sich irgend eine Nomenklatur 
ausdenken und darauf aufbauend abenteuerliche Namen erfinden. Deren 
Bedeutung hat man nämlich nach 3 tagen vergessen und dann fängt das 
Suchen zwecks Wiederverstehen an.

W.S.

von Zeno (Gast)


Lesenswert?

Clemens M. schrieb:
> Um mal Zenos Punkt zu stützen kann man auch wieder relativieren.

Endlich mal einer, der sich wenigstens bemüht einen anderen Denkansatz 
nachzuvollziehen und nicht starr auf irgendwelchen  Dogmen beharrt.


Clemens M. schrieb:
> Aber was wieder unstreitbar ist, das ist die Tatsache, dass die nackte
> Konstante 100 hier nicht mystisch ist.
Jetzt wird mir was klar: Ich hätte an Stelle von 0x02 lieber 4 schreiben 
sollen, dann hätte es vielleicht die Diskussion so gar nicht gegeben. Da 
wir uns hier aber in einem Mikrocontrollerforum befinden, bin ich davon 
ausgegangen, das das Umrechnen einer kleinen Hexzahl in eine Dezimalzahl 
kein Problem darstellt. Ich habe mich offensichtlich schwer getäuscht. 
Aber ich bin ja schon froh das ich es nicht als Binärzahl oder Oktalzahl 
geschrieben habe. Was hätte das wohl gegeben?


Zeno

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


Lesenswert?

W.S. schrieb:
> Jörg, du willst sicherlich nicht behaupten, daß dieses Zitat lesbarer
> sei als wenn dort mit schnöden (1<<xyz) gearbeitet worden wäre und
> hinter dem Statement ein erhellender Kommentar stünde.
> Also (ohne Anspruch auf Richtigkeit) etwa so:
>   UEINTX &= ~(1<<7);  // reset für TX ein

Das Löschen des Interruptflags hätte man noch lesbarer machen können
(ist ja jedesmal dasselbe).  Darum ging es nicht.

Es ging um den Teil davor:

DIR_IN | RQTYPE_STANDARD | RQRCPT_DEVICE

kann man, wenn man ein wenig in den USB-Standard geguckt hat, auch
nach einem Jahr noch sofort zuordnen, während man die Bitwerte nach
dieser Zeit getrost wieder vergessen hat.

Wenn dort stattdessen 0x47 steht, guckst du jedesmal im Standard nach.

von Daniel A. (daniel-a)


Lesenswert?

Zeno schrieb:
> Jetzt wird mir was klar: Ich hätte an Stelle von 0x02 lieber 4 schreiben
> sollen, dann hätte es vielleicht die Diskussion so gar nicht gegeben. Da
> wir uns hier aber in einem Mikrocontrollerforum befinden, bin ich davon
> ausgegangen, das das Umrechnen einer kleinen Hexzahl in eine Dezimalzahl
> kein Problem darstellt.

Ja, sollte man annehmen. Übrigens, 0x02 ist dezimal 2 und nicht 4.

von M. K. (sylaina)


Lesenswert?

Karl Käfer schrieb:
> Wenn wir hier schon beim Korinthenkacken sind, dann bitte wenigstens
> richtig: Fehler sollen nämlich nicht beseitigt werden, sondern Fehler
> müssen beseitigt werden. Das unterscheidet sie von Warnungen, die nur
> beseitigt werden sollen, aber nicht müssen.

Yo, das ist völlig richtig.

von chris_ (Gast)


Lesenswert?

Ich hätte da noch einen:
Beitrag "goto in c warum"

von Mark B. (markbrandis)


Lesenswert?

Zeno schrieb:
> Jetzt wird mir was klar: Ich hätte an Stelle von 0x02 lieber 4 schreiben
> sollen, dann hätte es vielleicht die Diskussion so gar nicht gegeben. Da
> wir uns hier aber in einem Mikrocontrollerforum befinden, bin ich davon
> ausgegangen, das das Umrechnen einer kleinen Hexzahl in eine Dezimalzahl
> kein Problem darstellt.

Dir bereitet es offensichtlich Probleme, denn hexadezimal zwei ist exakt 
das Gleiche wie dezimal zwei.

X zur Basis A ist stets das Gleiche wie X zur Basis B, sofern X eine 
Ziffer ist die in beiden Zahlensystemen existiert.

Edit: Du Held! ;-)

: Bearbeitet durch User
von Michael S. (rbs_phoenix)


Lesenswert?

Karl Käfer schrieb:
> Michael S. schrieb:
>> M. K. schrieb:
>>> Ich sehe da nicht, dass ich schrieb man solle Fehler nicht beseitigen.
>>> Hab vielleicht was auf der Brille.
>>
>> Wenn du
>> also sagst, der Unterschied zwischen Fehlern und Warnungen ist, dass
>> eine Warnung beseitigt werden soll, heißt es im Umkehrschluss, ein
>> Fehler soll nicht beseitigt werden. Sonst wäre es kein Unterschied. Ich
>> glaub aber auch, dass jeder weiß, dass du das so nicht gemeint hast,
>> sondern nur sagen wolltest, dass Warnungen im allgemeinen beseitigt
>> werden sollen, Fehler natürlich ebenso.
>
> Wenn wir hier schon beim Korinthenkacken sind, dann bitte wenigstens
> richtig: Fehler sollen nämlich nicht beseitigt werden, sondern Fehler
> müssen beseitigt werden. Das unterscheidet sie von Warnungen, die nur
> beseitigt werden sollen, aber nicht müssen.

Ansich hatte ich auch nur versucht, mit anderen Worten zu erklären, was 
(ich glaube) Rolf meinte. Auch wenn man wieder "streiten" könnte, ob 
"müssen" auch "sollen" impliziert oder dass M.K.'s exaktes Zitat ist 
"Ich sehe da nicht, dass ich schrieb man solle Fehler nicht 
beseitigen." (es war also kein Wort von müssen), würde ich das Thema 
gerne auf sich beruhen lassen. Jeder weiß, was gemeint ist, letztendlich 
geht es nur um den Wortlaut. Ähnlich sinnvoll, wie sich bei einem 
"for(;;;)" aufzuspielen, dass derjenige doch keine Ahnung hat, wie eine 
for-Schleife geschrieben wird. Daher find ich es auch müßig so groß 
darüber zu diskutieren. Ehrlich gesagt hab ich das schon abgehakt, weil 
es gefühlt 300 Beiträge zurück liegt ;)


W.S. schrieb:
> Michael S. schrieb:
>>> It is good programming style to use the break, continue, and return statements
>>> instead of the goto statement whenever possible.
>
> OK Michael, das war ein Zitat und nicht von dir, nun ja.
>
> Aber "whenever possible" ???
>
> Das ist ne Unverschämtheit.
>
> Da will mir ( MIR!! ) irgend jemand vorschreiben, was guter
> Programmierstil ist. Und das soll sich darin ausdrücken, daß man alles
> andere außer goto zu verwenden hat "whenever possible"? Dreistigkeit
> sowas! Frechheit!

Ich kann und will auch garnicht urteilen, wann welcher Befehl Sinn 
macht. Und ich würde auch nicht sagen, dass dir das jemand vorschreiben 
will, sondern was eine Empfehlung seitens Microsoft ist. Es wird auch 
empfohlen, Red-Bull nicht mit Alkohol zu mischen, doch es wird auch 
niemandem verboten ;)

von Mitlesender (Gast)


Lesenswert?

Daniel A. schrieb:
> Ja, sollte man annehmen. Übrigens, 0x02 ist dezimal 2 und nicht 4.

Stimmt! Ich habe mich vertan - war irgendwie bei Byte. Aber trotz meines 
Fehlers hast Du den Sinn Posts verstanden.

Mark B. schrieb:
> Dir bereitet es offensichtlich Probleme, denn hexadezimal zwei ist exakt
> das Gleiche wie dezimal zwei.

Schön für Dich das Du den Fehler gefunden hast - darfst ihn gern 
behalten.

Schön für Dich, daß Du keine Fehler machst.

Es ging hier ums Prinzip und Daniel hat's offensichtlich erkannt.

von Paul B. (paul_baumann)


Lesenswert?

Michael S. schrieb:
> Es wird auch
> empfohlen, Red-Bull nicht mit Alkohol zu mischen, doch es wird auch
> niemandem verboten ;)

Goto verleiht Flügel!
;-)

Man kann damit aus einer Routine abzwitschern und damit Chaos 
hinterlassen.
Schöner ist "Exit Do" oder "Exit For". Das gibt es in Bascom -und auch 
noch andere Exite.

MfG Paul

von Mark B. (markbrandis)


Lesenswert?

Mitlesender schrieb:
> Es ging hier ums Prinzip und Daniel hat's offensichtlich erkannt.

Das Prinzip ist, dass man magic numbers vermeidet. Schön wenn Du es 
irgendwann erkennst.

von Daniel A. (daniel-a)


Lesenswert?

Mitlesender schrieb:
> Schön für Dich, daß Du keine Fehler machst.
>  Es ging hier ums Prinzip und Daniel hat's offensichtlich erkannt

Nö, ich hab mich nur auf das Zitierte bezogen und stimme der meinung des 
damals Zitierten nicht zu. Meine Aussage war Sarkastisch zu verstehen 
(wir brauchen in diesem Forum unbedingt Ironie und Sarkasmus tags...)

https://de.m.wikipedia.org/wiki/Sarkasmus

von Eric B. (beric)


Lesenswert?

Paul B. schrieb:
> Man kann damit aus einer Routine abzwitschern und damit Chaos
> hinterlassen.

...dann sei no nett und benutz' die Bürste :-P

von Paul B. (paul_baumann)


Lesenswert?

Ich mach' ein Selfie-Foto
Arm in Arm mit meinem GOTO
und schreib dazu noch einen Text
das nehm' ich mir fest FOR
demNEXT!

MfG Paul

von Stefan (Gast)


Lesenswert?


von berndl (Gast)


Lesenswert?

Mark B. schrieb:
> Wir warten immer noch auf ein wirklich gutes Beispiel, welches diese
> Aussage untermauert.

https://www.kernel.org/doc/Documentation/CodingStyle
Chapter 7: Centralized exiting of functions

Ist m.M. nach ein gutes Beispiel fuer goto

Oder wenn du eine Sequenz hast, die schief gehen kann und aus mehreren 
sequentiellen Schritten besteht (z.B. File oeffnen, File parsen, ...). 
Dann "kann" goto uebersichtlicher sein als Gazillionen von Einrueckungen 
und breaks und exits.

Fuer ein paar wenige Anwendungsfaelle ist mir ein goto lieber als all 
die anderen verkrampften Sachen...

von W.S. (Gast)


Lesenswert?

Michael S. schrieb:
> Ich kann und will auch garnicht urteilen, wann welcher Befehl Sinn
> macht.

Ich schon.
Aber daeum geht's bei dem Zitat auch garnicht. Hätte der Urheber 
geschrieben, man möge mit goto sparsam umgehen und es nicht allzuhäufig 
verwenden, weil es ja auch noch andere Sprachelemente in der 
betreffenden Programmiersprache gibt, dann hätte ich ihm glatt 
zugestimmt.

Aber es als "guten Programmierstil" zu predigen, daß man goto "whenever 
possible" zu vermeiden habe, das ist der Moment, wo einem solchen 
Prediger der nächstbeste Feudel um die Ohren gehört.

Leute, wir leben in einer Zeit, wo der Extremismus und Fanatismus 
offensichtlich massiv im Kommen ist - ich kann davor nur warnen.

Bezogen auf die µC-Gefilde hat sich da was Ähnliches vor einigen Jahren 
abgezeichnet durch das Auftauchen der Arm-Cortex und bei den 
Programmiersprachen kam es schon 15 Jahre früher mit C. So ist es 
verstehbar, daß der geistige Horizont bei gar Vielen mittlerweile arg 
eingeschränkt ist und das ist ganz ganz schlecht. Auf lange Sicht 
verblöden wir alle, wenn wir uns nicht um Vielfalt bemühen und 
stattdessen die vorhandenen Ausdrucksmittel der wenigen noch vorhandenen 
Programmiersprachen aus purem Mutwillen verteufelt werden.

Also: Kommt mal wieder runter von euren jeweiligen Bäumen. Unseren 
Vorfahren hat es entwicklungsgeschichtlich gut getan, von den Bäumen zu 
klettern und sich ein vielfältiges Menü zu gönnen anstelle immer nur 
Banane zu essen.

W.S.

von Mark B. (markbrandis)


Lesenswert?

W.S. schrieb:
> Aber es als "guten Programmierstil" zu predigen, daß man goto "whenever
> possible" zu vermeiden habe

Ja, genau so ist es. Wann immer es eine bessere Möglichkeit als goto 
gibt, verwendet man diese auch. Und somit benutzt man goto nur in 
seltenen Ausnahmefällen.

Oder um es mit den Worten eines anderen auszudrücken:

"My take is that goto is fine, but only if it is adding value, never the 
default choice."

: Bearbeitet durch User
von Mark B. (markbrandis)


Lesenswert?

berndl schrieb:
> Oder wenn du eine Sequenz hast, die schief gehen kann und aus mehreren
> sequentiellen Schritten besteht (z.B. File oeffnen, File parsen, ...).
> Dann "kann" goto uebersichtlicher sein als Gazillionen von Einrueckungen
> und breaks und exits.

Das alles muss aber nicht zwingend innerhalb ein und derselben Funktion 
passieren. Und wenn ich die Schritte der Sequenz in einzelne Funktionen 
aufteile, dann kann habe ich das Problem mit den Einrückungen und breaks 
und exits sehr wahrscheinlich gar nicht mehr.

Viel Unbill lässt sich vermeiden, wenn man die Software-Design-Regel aus 
dem sehr lesenswerten Buch "Clean Code" befolgt: One function does only 
one thing.

von geh (Gast)


Lesenswert?

Goto ist nur was für richtige Männer.

von Paul B. (paul_baumann)


Lesenswert?

geh schrieb:
> Goto ist nur was für richtige Männer.

Es gibt durchaus auch Frauen,
die sich an GOTO trauen!

MfG Paul

von nichtCler (Gast)


Lesenswert?

W.S. schrieb:
> ..., das ist der Moment, wo einem solchen
> Prediger der nächstbeste Feudel um die Ohren gehört.
>
> Leute, wir leben in einer Zeit, wo der Extremismus und Fanatismus
> offensichtlich massiv im Kommen ist - ich kann davor nur warnen.

Jawoll und muß auch mit dem "nächstbesten Feudel" unterdrückt werden. 
Aber wen willst du vor wem warnen?

von dummschwaetzer (Gast)


Lesenswert?

da nehm ich
#pragma diag_suppress= ###
//der code der die Warnung wirft
#pragma diag_warning= ###

von Michael S. (rbs_phoenix)


Lesenswert?

W.S. schrieb:
> Michael S. schrieb:
>> Ich kann und will auch garnicht urteilen, wann welcher Befehl Sinn
>> macht.
>
> Ich schon.

Ich hab, wieso auch immer, nicht das geschrieben, was ich meine. 
Natürlich weiß ich, wann welcher Befehl Sinn macht, sonst würde ja kein 
Programm laufen. Ich meinte: Ich kann und will niemanden vorschreiben, 
was er wie zu programmieren hat. Macht an der Stelle auch (mehr) Sinn.


W.S. schrieb:
> Leute, wir leben in einer Zeit, wo der Extremismus und Fanatismus
> offensichtlich massiv im Kommen ist - ich kann davor nur warnen.

Da geb ich dir zwar in gewisser Weise recht, aber es gibt gefühlt 5 
Millionen andere Formen von Extremismus, die schlimmer sind und eher 
beseitigt werden sollten, als der verwende-kein-goto-Extremismus ;)


Paul B. schrieb:
> Ich mach' ein Selfie-Foto
> Arm in Arm mit meinem GOTO
> und schreib dazu noch einen Text
> das nehm' ich mir fest FOR
> demNEXT!

Paul B. schrieb:
> Es gibt durchaus auch Frauen,
> die sich an GOTO trauen!

Reime-Monster ;)

von MCUA (Gast)


Lesenswert?

> Und wenn ich die Schritte der Sequenz in einzelne Funktionen aufteile..
einzelne Funktionen kosten in der Regel jedoch viel mehr CPU-Rechenzeit

von Zeno (Gast)


Lesenswert?

Warum gibt es eigentlich für C so viele Abhandlungen darüber wie man 
sauberen Code schreibt? Und warum gibt ebenso massenhaft Tools die dann 
überprüfen ob man sich an Vorgaben gehalten? Und es werden immer mehr 
solche Tools, zumindest bekommt man diesen Eindruck Jahr für Jahr auf 
der Embedded.

Das Ganze muß ja wohl einen Grund haben, denn bei anderen 
Programmiersprachen ist mir das so massiv noch nicht aufgefallen. Nur 
das C so weit verbreitet ist kann da nicht der Grund sein. Ich befürchte 
eher das bei C zu viele Schweinereien möglich sind, wo andere Compiler, 
mit Recht, einem gehörig auf die Finger hauen.

Kann mir das mal einer erklären?


Zeno

von M. K. (sylaina)


Lesenswert?

Zeno schrieb:
> Warum gibt es eigentlich für C so viele Abhandlungen darüber wie man
> sauberen Code schreibt?

Gibts doch für C++ und Java auch. Da gibts IMO gefühlt keinen 
Unterschied.

Zeno schrieb:
> Nur
> das C so weit verbreitet ist kann da nicht der Grund sein.

trägt aber mit Sicherheit nicht unwesentlich dazu bei

Zeno schrieb:
> Ich befürchte
> eher das bei C zu viele Schweinereien möglich sind

Das ist aber auch der Preis, den man für die, ich sag mal, Flexibilität 
von C zahlen muss/darf.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Zeno schrieb:
> Warum gibt es eigentlich für C so viele Abhandlungen darüber wie man
> sauberen Code schreibt?

> Nur das C so weit verbreitet ist kann da nicht der Grund sein.

Doch, das ist IMHO der Hauptgrund. Insbesondere bei sichheitskritischen
Steuerungsanwendungen (bspw. in der Auto- und Flugzeugindustrie) ist C
noch viel stärker präsent als anderswo, wo mittlerweile auch C++ und
Java weit verbreitet sind.

> Und warum gibt ebenso massenhaft Tools die dann überprüfen ob man sich
> an Vorgaben gehalten?

In den genannten sichheitskritischen Bereichen sind solche Prüf-Tools
üblich und und oft sogar Pflicht.

von Paul B. (paul_baumann)


Lesenswert?

Yalu X. schrieb:
> Insbesondere bei sichheitskritischen
> Steuerungsanwendungen (bspw. in der Auto- und Flugzeugindustrie) ist C
> noch viel stärker präsent als anderswo,...

Ich glaube, es ist dann besser, nur noch Fahrrad zu fahren.

MfG Paul

von Yalu X. (yalu) (Moderator)


Lesenswert?

Paul B. schrieb:
> Ich glaube, es ist dann besser, nur noch Fahrrad zu fahren.

Nur zu! Ist ja auch viel gesünder und umweltschonender :)

Oder noch besser: GOTO Fuß :D

von Herbert P. (Gast)


Lesenswert?

Im Hobbybereich kann jeder gerne programmiertechnisch tun und lassen, 
was ihm oder ihr Spaß macht, aber in der Industrie schaut das sowieso 
anders aus. Im sicherheitskritischen oder automotive Bereich gelten 
strenge Standards, die verbindlich einzuhalten sind, z.B. MISRA-C:2012 
und da lautet eine Regel knapp und klar: "Do not use goto." Nicht 
zuletzt deshalb gilt diese Regel auch in meinen Vorlesungen und Übungen, 
obwohl sie meine Studierenden auch immer wieder gerne wegdiskutieren 
wollen...

In diesem Sinn: fröhliches Weiterdiskutieren. :)

Herby

von Cube_S (Gast)


Lesenswert?

Das GOTO bzw. das bedingte GOTO ist die Quintessenz der Ablaufsteuerung 
seit Zuses Zeiten. Alles was danach an Schleifenkonstruktionen kam ist 
menschliche Eitelkeit gepaart mit Bequemlichkeit.

von Falk B. (falk)


Lesenswert?

@  Cube_S (Gast)

>Das GOTO bzw. das bedingte GOTO ist die Quintessenz der Ablaufsteuerung
>seit Zuses Zeiten. Alles was danach an Schleifenkonstruktionen kam ist
>menschliche Eitelkeit gepaart mit Bequemlichkeit.

Unsinn. Da kannst du ja gleich bei der Turingmaschine bleiben und 
sämtliche höhere Abstraktion weglassen. VIEL SPAß!

von Cube_S (Gast)


Lesenswert?

Immer locker bleiben. Natürlich sind höhere Abstraktionen schön und 
nützlich. Aber in ganz seltenen Fällen kann ein GOTO schon mal 
ästhetischer sein als irgendwelche Hilfsvarieblen, die nur dazu da sind 
das GOTO zu vermeiden. Wem die künstlerische Freiheit sagt es zu nutzen, 
der soll es tun ohne über Tabus nachzudenken.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Cube_S schrieb:
> Das GOTO bzw. das bedingte GOTO ist die Quintessenz der Ablaufsteuerung
> seit Zuses Zeiten.

Nur so am Rande:

Die frühen Zuse-Rechner kannten noch keine Gotos und auch sonst keine
Sprungbefehle. Stattdessen konnte man eine sprungfreie Schleife¹
"programmieren", was auf heutigen Rechnern nicht mehr geht. Damals war
eben noch sauberes Programmieren angesagt ;-)

——————————
¹) Der der Begriff "Schleife" ist hier wörtlich zu nehmen.

von Chris F. (chfreund) Benutzerseite


Lesenswert?

GOTO macht in C bei einigen Fällen Sinn. Meistens kommen Anfänger mit 
diesen Stellen aber nicht in Berührung. ;-)
Das ist ein Sprachmittel wie jedes andere auch und Du musst Dir 
überlegen was in Deinem Anwendungsfall das Effektivste ist.

von Mark B. (markbrandis)


Lesenswert?

MCUA schrieb:
>> Und wenn ich die Schritte der Sequenz in einzelne Funktionen aufteile..
> einzelne Funktionen kosten in der Regel jedoch viel mehr CPU-Rechenzeit

Das mag vielleicht noch zutreffen, wenn man einen kleinen 8-Bit 
Mikrocontroller mit wenigen Registern, wenig Hauptspeicher und niedriger 
Taktfrequenz benutzt. Und diesen quasi schon "am Anschlag" betreibt.

Es gibt also sehr viele Projekte, in denen Mangel an Hardware-Ressourcen 
schon lange kein Grund mehr ist, möglichst viel Code in eine Funktion zu 
packen.

von Rasputin (Gast)


Lesenswert?

Zu dem Thema hab ich auch ein lustiges Fundstück:
1
#define MAXINT 200000
2
3
int main(void) 
4
{
5
    unsigned int t=1000, k=0, l=5, pn=2; 
6
    unsigned int primes[t];
7
    primes[0]=2;
8
    primes[1]=3;
9
10
    while (pn < t || primes[pn] < MAXINT)
11
    {
12
        for ( k = 0; k <= pn; k++)
13
        {
14
            if (l % primes[k] == 0)
15
      {
16
                goto otog;
17
      }
18
            else 
19
            {
20
                if (k == pn)
21
                    primes[pn++]=l;
22
            } 
23
        }
24
otog:
25
        l += 2;
26
    }
27
    return 0;
28
}

Dieser Code stammt aus der Atmel Studio 7.0 Hilfe. Zu finden unter 
Getting started > Creating a project > Writing and Compiling Code.

Abgesehen davon, dass dieser Code fehlerhaft ist, ist er ausserdem ein 
unfreiwilliges, aber treffendes Beispiel für einen unnötigen Einsatz von 
goto. ;)

von Falk B. (falk)


Lesenswert?

Auch bei Atmel arbeiten billige Praktikanten und Frickler . . .

von Paul B. (paul_baumann)


Lesenswert?

>> Ich glaube, es ist dann besser, nur noch Fahrrad zu fahren.
Yalu X. schrieb:
> Nur zu! Ist ja auch viel gesünder und umweltschonender :)
>
> Oder noch besser: GOTO Fuß :D

Ich glaube, daß ich mit meiner Aussage mindestens 2 Mann auf die C-hen 
getreten bin.

Das ist mir aber ziemlich Brust.
;-)

MfG Paul

von Cube_S (Gast)


Lesenswert?

> Abgesehen davon, dass dieser Code fehlerhaft ist

Warum? Der Return-Wert ist 0. Das stimmt doch.

von W.S. (Gast)


Lesenswert?

Falk B. schrieb:
> @  Cube_S (Gast)
>
>>Das GOTO bzw. das bedingte GOTO ist die Quintessenz der Ablaufsteuerung
>>seit Zuses Zeiten. Alles was danach an Schleifenkonstruktionen kam ist
>>menschliche Eitelkeit gepaart mit Bequemlichkeit.
>
> Unsinn.

Eben kein Unsinn. Derjenige, der hier mal wieder mit haltlosen 
Behauptungen um sich wirft, bist du.

Das GOTO bzw. eben das mit einer Bedingung versehene GOTO sind die 
Fundamente jeglicher Programmierung. Ohne dieses könnte niemand 
irgendeine Entscheidung in einem Programm treffen oder irgend eine 
Schleife realisieren.

Daß es mittlerweile diverse Aufsätze auf dieses grundlegende GOTO gibt 
(namens if..then, while.., repeat..until und wie sie alle heißen mögen), 
ist eben nur Zuckerwerk obendrauf.

Dies solltest du mal begreifen, bevor du jemandem "Unsinn" an den Kopf 
wirfst, der die Sache weitaus besser verstanden hat als du.

Solch hirnrissige Dogmatismen wie die hier diskutierte Verpönung von 
GOTO findet sich in keiner anderen Sparte - oder hat schon mal jemand 
von einer Verunglimpfung von GOTO oder anderen Sprachelementen in 
Pascal- oder Delphi- oder Basic-Gefilden oder sonstwo gehört? Nee, alle 
anderen machen nicht so einen Fanatismus auf - das findet sich eben nur 
unter C-Jüngern.

Aber so langsam langweilt mich dieser Thread.

Augen-Tinnitus meinerseits?

Ich will ja nicht grob werden (obwohl das angemessen wäre).

Aber mir fällt da wieder ein alter Juwelierspruch ein, den mal jemand 
aufgeweitet hatte und den ich hier nochmal aufweiten will:

"Frauen und Edelsteine (und C-Programmierer) haben eine Gemeinsamkeit: 
Man erkennt ihren wahren Wert erst dann, wenn man sie mal aus der 
Fassung gebracht hat." Und hier haben sich manche vorgeblichen 
Hochkaräter als poplige Fälschungen erwiesen.


W.S.

von Bernd K. (prof7bit)


Lesenswert?

W.S. schrieb:
> oder hat schon mal jemand
> von einer Verunglimpfung von GOTO oder anderen Sprachelementen in
> Pascal- oder Delphi-

Ja, auch da gilt das selbe, im Falle von (Object-)Pascal eher sogar noch 
stärker als bei C(++) da dort sowohl sprachlich als auch kulturell 
bedingt die Meßlatte für sauberen Code nochmal gut zwei Meter höher 
liegt als bei C oder C++.

von Thorsten .. (tms320)


Lesenswert?

> Im Netz wird da von gesprochen, das es verpöönt ist nichrr genutzt
> werden soll.
> Was nutz ihr bei solchen Sachen?
> Paul

Wen interessiert, was im Netz steht. Wenn es für dich eine praktikable 
Lösung ist, mach es halt.

von Falk B. (falk)


Lesenswert?

@ W.S. (Gast)

>Eben kein Unsinn. Derjenige, der hier mal wieder mit haltlosen
>Behauptungen um sich wirft, bist du.

Jaja . .

>Daß es mittlerweile diverse Aufsätze auf dieses grundlegende GOTO gibt
>(namens if..then, while.., repeat..until und wie sie alle heißen mögen),
>ist eben nur Zuckerwerk obendrauf.

Falsch. Es ist deutlich mehr als Zuckerwerk. Mit dem "Verbieten" des 
klassischen Spaghetti-Goto hat man die Programmierung deutlich 
verbessert.

>Dies solltest du mal begreifen, bevor du jemandem "Unsinn" an den Kopf
>wirfst, der die Sache weitaus besser verstanden hat als du.

Der Papst?

>Solch hirnrissige Dogmatismen

Dogmen.

> wie die hier diskutierte Verpönung von
>GOTO findet sich in keiner anderen Sparte - oder hat schon mal jemand
>von einer Verunglimpfung von GOTO oder anderen Sprachelementen in
>Pascal- oder Delphi- oder Basic-Gefilden oder sonstwo gehört?

Dort wird es genauso wenig benutzt und ist ebenso unnötig im normalen 
Programmiereraltag wie in C.

>Aber so langsam langweilt mich dieser Thread.

Na dann geh woanders deine Weisheiten ablassen.

>Ich will ja nicht grob werden (obwohl das angemessen wäre).

Uhhhh, wir zittern schon ;-)

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


Lesenswert?

Herbert P. schrieb:
> Im sicherheitskritischen oder automotive Bereich gelten
> strenge Standards, die verbindlich einzuhalten sind, z.B. MISRA-C:2012
> und da lautet eine Regel knapp und klar: "Do not use goto."

diese Behauptung zeigt einmal mehr, was für fanatisch religiöse Züge die 
Debatte hat.

Erstens ist die Regel nicht klipp und klar (mandatory), noch nicht mal 
„required”, sondern bloß advisory und zweitens folgt aus der Ergänzung 
in MISRA-C 2012:

• The goto statement shall jump to a label declared later in the same 
function.

• Any label referenced by a goto statement shall be declared in the same 
block, or in any block enclosing the goto statement.

Das Gotos verwendet werden und verwendet werden dürfen.

Aber Hauptsache Du kannst in Deinen Vorlesungen und Übungen den 
Soziopathen raushängen lassen.

Vlg

 Timm

von Zeno (Gast)


Lesenswert?

Paul B. schrieb:
> Ich glaube, daß ich mit meiner Aussage mindestens 2 Mann auf die C-hen
> getreten bin.

Mit Sicherheit!


Bernd K. schrieb:
> Ja, auch da gilt das selbe, im Falle von (Object-)Pascal eher sogar noch
> stärker als bei C(++) da dort sowohl sprachlich als auch kulturell
> bedingt die Meßlatte für sauberen Code nochmal gut zwei Meter höher
> liegt als bei C oder C++.

Das sehe ich genau so. Zwar wird auch in einschlägiger Literatur zu 
Pascal geschrieben, daß man auf GOTO wenn möglich verzichten sollte, 
aber es wird nicht verboten. Es gibt ja auch keinen Grund dafür. Wenn 
man es sparsam und überlegt einsetzt, kann man dennoch gut lesbaren und 
verständlichen Code schreiben.
Bei keiner anderen Programmiersprache wird so ein Geschrei um GOTO 
gemacht wie bei C und insofern muß ich W.S. einfach recht geben, wenn er 
schreibt:
W.S. schrieb:
> Solch hirnrissige Dogmatismen wie die hier diskutierte Verpönung von
> GOTO findet sich in keiner anderen Sparte


Herbert P. schrieb:
> aber in der Industrie schaut das sowieso
> anders aus. Im sicherheitskritischen oder automotive Bereich gelten
> strenge Standards, die verbindlich einzuhalten sind, z.B. MISRA-C:2012
> und da lautet eine Regel knapp und klar: "Do not use goto."
Natürlich gelten in der Industrie andere Maßstäbe als im privaten 
Bereich und speziell im bei sicherheitsrelevanten Dingen ist es wichtig, 
daß man Standards setzt. Ob es nun da Sinn macht GOTO zu verbieten 
möchte ich bezweifeln. Ich glaube nicht, das ein Auto gegen einen Baum 
fährt, bloß weil ein Programmierer GOTO benutzt hat. Die FW eines 
Controllers im Auto schmiert dann eher wegen anderer Unzulänglichkeiten 
in C ab, z.B. Speicherlecks, die es so massiv nur in C gibt. In keiner 
anderen mir bekannten Programmiersprache ist es z.B. möglich über ein 
Array hinaus zu schreiben. Genau dies ist ja auch eine oft genutzte 
Möglichkeit um ein OS zu kompromitieren.

In C sind einfach zu viele Schweinereien möglich und genau deshalb gibt 
es so unzählig viele Richtlinien und Codekontrolltools. Solche Dinge wie 
zum Beispiel die for-Schleife ohne Argumente gibt es in anderen 
Programmiersprachen nicht und das ist gut so.


Ich habe mir grad mal die Quellen von RTOS downgeloaded und dort nach 
goto gesucht. Wie nicht anders zu erwarten, wurden 200 Dateien gefunden 
wo goto benutzt wird und das nicht nur beim Errorhandling wie dieser 
Auszug aus tcp.c zeigt:
1
 again:
2
  if (port++ >= TCP_LOCAL_PORT_RANGE_END) {
3
    port = TCP_LOCAL_PORT_RANGE_START;
4
  }
5
  /* Check all PCB lists. */
6
  for (i = 0; i < NUM_TCP_PCB_LISTS; i++) {
7
    for(pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) {
8
      if (pcb->local_port == port) {
9
        goto again;
10
      }
11
    }
12
  }
13
  return port;
14
}

Sind das jetzt alles Deppen? Nein diese Leute wissen ganz genau was sie 
tun. RTOS ist im übrigen auch für Software im medizinischen Bereich 
zertifiziert und dort sind die Anforderungen noch härter als in der 
Automobilindustrie.

Zeno

von Zeno (Gast)


Lesenswert?

Timm R. schrieb:
> Erstens ist die Regel nicht klipp und klar (mandatory), noch nicht mal
> „required”, sondern bloß advisory und zweitens folgt aus der Ergänzung
> in MISRA-C 2012:

Ha da war mal einer der sich offenbar auskennt schneller als ich. Schön 
das sich endlich mal Leute zu Wort melden die sich in 
Industrierichtlinien offenbar gut auskennen und die eigentlich 
unbegründeten Richtlinien schlichtweg widerlegen. Ich nehme mal an Timm 
verdient seine Brötchen damit, denn sonnst könnte er nicht so detailiert 
Auskunft geben - das ist schon Insiderwissen.

Zeno

von M. K. (sylaina)


Lesenswert?

Zeno schrieb:
> Die FW eines
> Controllers im Auto schmiert dann eher wegen anderer Unzulänglichkeiten
> in C ab, z.B. Speicherlecks, die es so massiv nur in C gibt.

Speicherlecks liegen aber nie in der Sprache begründet sonderen sind 
immer auf Unzulänglichkeiten des Programmieres zurück zu führen. Ein 
beliebter, meiner Erfahrung nach, Anfängerfehler ist, dass man sich über 
das Memory Management erst Gedanken macht wenn das Programm fertig ist, 
da braucht man sich über Speicherlecks nicht wundern. Mit der Zeit, wenn 
man schon ein paar mal damit auf die Schnautze gefallen ist, wird auch 
das Memory Management besser.

von nichtCler (Gast)


Lesenswert?

Zeno schrieb:
> Ich habe mir grad mal die Quellen von RTOS downgeloaded und dort nach

Wer "downgeloaded" schreibt, bei dem gehört auch "goto" zum 
Sparchumfang.

von Mark B. (markbrandis)


Lesenswert?

W.S. schrieb:
> Das GOTO bzw. eben das mit einer Bedingung versehene GOTO sind die
> Fundamente jeglicher Programmierung.

Du ziehst einen unpassenden Maßstab für die Bewertung heran. Man 
programmiert heutzutage üblicherweise nicht mehr in Assembler, sondern 
in Hochsprachen ab der dritten Generation aufwärts. Somit ist Dein 
Argument nicht wirklich eins. Was der Compiler oder der Interpreter aus 
den üblichen Kontrollstrukturen macht, ist für den Programmierer im 
Endeffekt irrelevant (abgesehen von Compilerfehlern, die aber selten 
sind).

> Solch hirnrissige Dogmatismen wie die hier diskutierte Verpönung von
> GOTO findet sich in keiner anderen Sparte - oder hat schon mal jemand
> von einer Verunglimpfung von GOTO oder anderen Sprachelementen in
> Pascal- oder Delphi- oder Basic-Gefilden oder sonstwo gehört?

Selbstverständlich. Oder dachtest Du, Edsger Dijkstra (Autor) und 
Niklaus Wirth (Editor) haben sich speziell auf die Sprache C bezogen, 
als sie den berühmten Artikel "Go To Statement Considered Harmful" 
herausgaben?

Ich bleibe dabei: Wer heute noch goto verwendet, der macht sehr 
wahrscheinlich einen Fehler in seinem Software-Design.

Die ohnehin schon wenigen Fälle, in denen goto als akzeptabel gilt, 
beruhen meistens darauf dass zu viel Funktionalität in einer einzelnen 
Funktion steckt. Wenn man sein Software-Design verbessert, treten diese 
Konstellationen gar nicht mehr auf. Ergo gibt es dann auch keine 
"Notwendigkeit" mehr für goto.

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

@ Zeno (Gast)

>aber es wird nicht verboten. Es gibt ja auch keinen Grund dafür. Wenn
>man es sparsam und überlegt einsetzt, kann man dennoch gut lesbaren und
>verständlichen Code schreiben.

Das ist doch relativ unstrittig.

>Auszug aus tcp.c zeigt:

AUA!

>Sind das jetzt alles Deppen?

Jain. Auch in diesem Beispiel ist goto reine Faulheit oder Schlamperei.
Man gewinnt weder Performance noch Lesbarkeit. Und das "Verbot" von goto 
hat u.a. den Grund, das Codeanalysatoren für sauberen Code/MISRA etc. 
damit deutlich mehr Probleme haben als mit sauberen Kontrollstrukturen!

Und vielleicht bin ich ja auch nur beschränkt, aber irgendwie muss man 
bei dem Codeabschnitt ziemlich lange überlegen, WAS er bewirken soll und 
WIE der Ablauf grob ist? Im Extremfall wird daraus eine Endlosschleife 
;-)

>Nein diese Leute wissen ganz genau was sie
>tun.

Wirklich?

> RTOS ist im übrigen auch für Software im medizinischen Bereich
>zertifiziert

WELCHES RTOS?

> und dort sind die Anforderungen noch härter als in der
>Automobilindustrie.

Auch dort gab es schon üble Fehler. Einer der bekanntesten ist der hier.

http://www.ccnr.org/fatal_dose.html

https://en.wikipedia.org/wiki/Therac-25

1
  do {
2
    if (port++ >= TCP_LOCAL_PORT_RANGE_END) {
3
      port = TCP_LOCAL_PORT_RANGE_START;
4
    }
5
    /* Check all PCB lists. */
6
    for (i = 0; i < NUM_TCP_PCB_LISTS; i++) {
7
      for(pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) {
8
        if (pcb->local_port == port) break;
9
      }
10
      if (pcb->local_port == port) break;
11
    }
12
  } while (pcb->local_port == port);
13
14
  return port;
15
}

Das war jetzt echt schwer ohne goto . . .

von M. K. (sylaina)


Lesenswert?

Falk B. schrieb:
> Das war jetzt echt schwer ohne goto . . .

Ehrlich gesagt finde ich die Variante mit goto in dem Fall etwas 
übersichtlicher (!= besser).

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


Lesenswert?

Hallo,

ganz Deiner Meinung M. Köhler.

aus meiner persönlichen Sicht verfehlen die Goto-Verpöner an mehreren 
Stellen das Argumentationsziel. Es ist nicht zu beweisen, dass man auf 
das Goto verzichten  k a n n, das ist trivial klar und völlig 
unstrittig, sondern, dass man auf das Goto verzichten  s o l l t e.

Und zwar nicht unter Berufung auf das göttliche Gebot

thou shalt not goto

sondern durch Aufzeigen der negativen Konsequenzen des verwendeten Goto.

Außerdem wird – in meiner Wahrnehmung – die i.d.R. triviale Tatsache 
ignoriert, dass Code normalerweise sehr viel öfter gelesen wird, als 
geschrieben.

Weiter oben haben wir das USB Beispiel:
1
  case GET_DESCRIPTOR:
2
    if (bmRequestType == 0x80) usb_get_descriptor();
3
    else goto unsupported_request;
4
    break;

das goto springt nicht weit und es springt vorwärts. Durch die 
Verwendung des Goto dokumentiert der Programmierer für jeden 
Ahnungslosen sofort und ohne Nachdenken erkennbar, dass es keine andere 
Variante geben kann, als GET_DESCRIPTOR mit bmRequestType == 0x80. Dafür 
braucht der Leser weder Kenntnisse des USB Standards, noch sonst 
irgendwelches Wissen. Der Code ist schnell zu überblicken, klar 
strukturiert und logisch simpel. Mitternachtscode: Den versteht man auch 
nach 10 Stunden am Bildschirm noch, selbst wenn der Kaffee alle ist und 
ja, er ist, hinsichtlich der Anwendung des Goto, auch MISRA-C:2012 
konform.

Die von den Verpönern vorgeschlagene Variante
1
if (bRequest == GET_DESCRIPTOR && bmRequestType == 0x80)
2
        usb_get_descriptor();

hat auf der Pro-Seite, das Vermeiden von Goto. Allerdings werden in 
diesem Fall auch bei einem nicht unterstützen Request noch 7 weitere 
Bedingungen überprüft (mehr Code ausgeführt) und der Leser muss durch 
Analyse von 8 Bedingungen herausfinden, dass sie exklusiv und frei von 
Mehrfachnennungen sind.

Im Ergebnis wurde zwar ein religiöses Gebot befolgt, die Lesbarkeit aber 
objektiv verschlechtert und die Ausführung verlangsamt.


Im RTOS Beispiel oben:
1
again:
2
  if (port++ >= TCP_LOCAL_PORT_RANGE_END) {
3
    port = TCP_LOCAL_PORT_RANGE_START;
4
  }

haben wir eine Erhöhung der Anzahl der Lese-Zeilen von 7 auf 9 und eine 
Erhöhung der Anzahl der Kontrollstrukturen von 4 auf 6. Zusätzlich haben 
wir etwas, das ich persönlich, viel viel schlimmer finde, das aber 
definitiv mindestens genau so verpönt ist: duplicate code. Drei mal 
hintereinander die exakt identische Bedingung?
1
        if (pcb->local_port == port) break;
2
      }
3
      if (pcb->local_port == port) break;
4
    }
5
  } while (pcb->local_port == port);

Ob der Compiler erkennt, dass der Fall, dass nur eine dieser Bedingungen 
greift nie auftreten kann, vermag (und will) ich nicht einschätzen, das 
hängt wahrscheinlich vom Optimierungslevel ab, der Leser muss das 
jedenfalls auch erstmal kurz überprüfen. Das dauert keine zwei Sekunden, 
aber vermutlich schaut man auch erstmal fünf mal hin, weil man sich gar 
nicht vorstellen kann, dass jemand soetwas ohne perverse Hintergedanken 
geschrieben haben könnte.

Im Resultat:
1 religiöses Gebot befolgt, Lesbarkeit verschlechtert, redundanten Code 
reingebastelt und je nach Optimierung möglicherweise sogar mehr Code in 
der Ausführung.


Bewiesen wurde nur, dass es auch ohne Goto  g e h t, das ist aber gar 
nicht die zu beurteilende Frage. Argumente, warum die komplexeren 
Varianten  b e s s e r  sind, wurden nicht mal in homöopathischer 
Dosierung gebracht, abgesehen eben vom fast schon satirischen 
reiterieren der Regel oder Beleidigungen („Lernt doch mal Logik”).

Nur meine 2 Cent.

vlg
 Timm

: Bearbeitet durch User
von Mark B. (markbrandis)


Lesenswert?

Timm R. schrieb:
> sondern durch Aufzeigen der negativen Konsequenzen des verwendeten Goto.

Sieh es doch mal so herum: Warum verwendet jemand goto?

Vermutlich weil er ein ungünstiges Software-Design gewählt hat. Er 
"repariert" damit quasi ein Problem - aber dieses Problem hätte er gar 
nicht erst zu haben brauchen.

Wer vernünftiges Software-Design betreibt und sich an Regeln wie "One 
function does only one thing" hält, der wird auch ohne goto auskommen.


Timm R. schrieb:
> Die von den Verpönern vorgeschlagene Variante

Das beweist überhaupt gar nichts.

Wenn man richtig ernsthaft über solche Dinge diskutieren will, muss man 
im Endeffekt bei den Requirements selbst anfangen. Nicht bei einer schon 
existierenden Implementierung, die bereits beliebig viele Entscheidungen 
des Programmierers und somit Einschränkungen enthält.

Wer einen halben Codeschnipsel als Ausgangspunkt wählt und dann steif 
und fest behauptet: "Aber diese Code ist so besser mit goto!", der hat 
das Problem nicht verstanden. Sehr wahrscheinlich war von vornherein die 
Aufteilung des Codes in Funktionen schon nicht besonders clever 
vorgenommen worden. Denn wenn sie es wäre, wäre dort zu 99,99999% 
niemals ein goto aufgetaucht.

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

@ Timm Reinisch (Firma: privatfrickler.de) (treinisch)

>haben wir eine Erhöhung der Anzahl der Lese-Zeilen von 7 auf 9 und

Vollkommen egal.

>wir etwas, das ich persönlich, viel viel schlimmer finde, das aber
>definitiv mindestens genau so verpönt ist: duplicate code. Drei mal
>hintereinander die exakt identische Bedingung?

Ja, das ist sicher nicht optimal und kein Paradebeispiel. Aber manchmal 
ist halt auch etwas Formalismus angesagt.

>jedenfalls auch erstmal kurz überprüfen. Das dauert keine zwei Sekunden,
>aber vermutlich schaut man auch erstmal fünf mal hin, weil man sich gar
>nicht vorstellen kann, dass jemand soetwas ohne perverse Hintergedanken
>geschrieben haben könnte.

Hä? Das GEGENTEIL ist der Fall!! Man sieht, daß alle drei Schleifen nach 
dem gleichen suchen, nämlich

pcb->local_port == port

So lange läuft die Suche.

>1 religiöses Gebot befolgt,

Es ist keine Religion, sondern ein Konzept. Schau dir mal echte 
Religionen und deren "Gedankenwelt" aka Brimborium an, besonders die, 
welche gern und oft Schlagzeilen macht (jaja OT).

> Lesbarkeit verschlechtert,

Keine Sekunde.

> redundanten Code reingebastelt

Nö, es ist halt 3x die gleiche Bedingung.

> und je nach Optimierung möglicherweise sogar mehr Code in
>der Ausführung.

Stimmt, aber da ist hier nicht entscheidend.

>nicht die zu beurteilende Frage. Argumente, warum die komplexeren

Komplex?

>Varianten  b e s s e r  sind, wurden nicht mal in homöopathischer
>Dosierung gebracht,

Kannst du lesen?

"Und das "Verbot" von goto
hat u.a. den Grund, das Codeanalysatoren für sauberen Code/MISRA etc.
damit deutlich mehr Probleme haben als mit sauberen Kontrollstrukturen!"

Wehret den Anfängen. Wenn einmal goto OK ist, wird es das irgendwann 
immer mehr. Und dann haben wir wieder den (Spaghtetti-)Salat.

von MCUA (Gast)


Lesenswert?

> Solch hirnrissige Dogmatismen wie die hier diskutierte Verpönung von
> GOTO findet sich in keiner anderen Sparte
Doch das gibts überall.

sogenannte Codeanalysatoren sollten kein Problem damit haben, "gültige" 
von "ungültigen" goto's zu unterscheiden (bsp.weise nur innerhalb eine 
Funkt. und nur vorwärts)

von Zeno (Gast)


Lesenswert?

M. K. schrieb:
> Speicherlecks liegen aber nie in der Sprache begründet sonderen sind
> immer auf Unzulänglichkeiten des Programmieres zurück zu führen.
JAEIN! Erst mal sind sie in der Sprache begründet, weil diese zu läßt, 
das man über Arraygrenzen hinaus schreiben kann. Und erst dann kommt der 
Programmierer, der auch nur ein Mensch ist und wie wir alle halt mal 
Fehler macht. Einfaches Beispiel Stringverarbeitung, eine Sache die C 
nicht wirklich kann. Du deklarierst ein Zeichenarray mit 10 Zeichen 
Länge und dann schreibst Du irgendwann mal einen String rein der 11 
Zeichen lang ist und schon ist es passiert. Eigentlich darfst Du ja nur 
9 Zeichen reinschreiben, weil das letzte Zeichen das berühmte 0 Byte 
ist, auch so eine  Krücke, damit C das Stringende erkennt. Schreibst Du 
10 Zeichen rein passiert erst mal nichts aber Du merkst es wenn Du den 
String wieder auslesen möchtest. Nicht nur das es keine Strings in C 
gibt, eben nur diese Zeichenarrays, kann C zu allem Überfluss noch nicht 
mal richtig mit Arrays umgehen und Du mußt ihm sagen wie lang Dein Array 
ist. Das sind Basics. Selbst so alte Programmiersprachen wie FORTRAN 
können das.

nichtCler schrieb:
> Wer "downgeloaded" schreibt, bei dem gehört auch "goto" zum
> Sparchumfang.
Stimmt! Bei Dir gehört es definitiv nicht zum "Sparchumfang" - Du kannst 
noch nicht einmal richtig deutsch. Wer im Glashaus sitzt sollte lieber 
nicht mit Steinen werfen.

Falk B. schrieb:
> Jain. Auch in diesem Beispiel ist goto reine Faulheit oder Schlamperei.
> Man gewinnt weder Performance noch Lesbarkeit ...
Ohne Dir jetzt zu nahe treten zu wollen, aber der zitierte Satz spricht 
schon für eine gewisse Arroganz bzw. Ignoranz.

Falk B. schrieb:
> Und vielleicht bin ich ja auch nur beschränkt, aber irgendwie muss man
> bei dem Codeabschnitt ziemlich lange überlegen, WAS er bewirken soll und
> WIE der Ablauf grob ist? Im Extremfall wird daraus eine Endlosschleife
> ;-)
Du kannst Dir ja die Quellen von www.freertos.org selbst mal anschauen, 
dann wird sich Dir der Codeschnipsel bestimmt erschließen. Speziell die 
von mir zitierte Quelldatei dürfte für einen Erfahrungsträger wie Dich 
kein Problem darstellen. Ich habe sie rein zufällig gewählt, es hätte 
auch eine andere treffen können, die ein goto-Befehl enthält. Ich wollte 
den Auszug nicht zu lang machen. Mir ging es nur um die Verwendung des 
goto.

Falk B. schrieb:
>> RTOS ist im übrigen auch für Software im medizinischen Bereich
>>zertifiziert
>
> WELCHES RTOS?

Genau das von mir zitierte.

Falk B. schrieb:
> Auch dort gab es schon üble Fehler. Einer der bekanntesten
Es gibt keine fehlerfreie Software! Da kannst Du noch so viele 
Codeanalyzer einsetzen wie Du möchtest, denn auch die sind nur von 
Menschen gemacht.

Timm R. schrieb:
> das goto springt nicht weit und es springt vorwärts. Durch die
> Verwendung des Goto dokumentiert der Programmierer für jeden
> Ahnungslosen sofort und ohne Nachdenken erkennbar  ....
Endlich mal einer der sachlich bleibt und die Sache nüchtern analysiert.
>>>> Chapeau! <<<<

Timm R. schrieb:
> hat auf der Pro-Seite, das Vermeiden von Goto. Allerdings werden in
> diesem Fall auch bei einem nicht unterstützen Request noch 7 weitere
> Bedingungen überprüft (mehr Code ausgeführt)
Der Bursche gefällt mir immer besser!

@Timm: Schau Dir nur mal die unmittelbar Deinem Post folgenden Posts an. 
Schlimm oder? Man will sich einfach nichts sagen lassen und beharrt stur 
und rechthaberich auf seinen Dogmen : "Wir vermeiden GOTO um jeden Preis 
koste es Codezeilen und Ressourcen was es wolle." Na gut gut geht eben 
auch so.

Mark B. schrieb:
> Wer einen halben Codeschnipsel als Ausgangspunkt wählt und dann steif
> und fest behauptet: "Aber diese Code ist so besser mit goto!", der hat
> das Problem nicht verstanden.
Du darfst Dir gern den kompletten Quelltext ansehen - die Quellen hatte 
ich ja genannt - und es dann besser machen. Vielleicht solltest Du aber 
auch mit RTOS-Entwicklern in Kontakt treten und ihnen zeigen, wie man es 
richtig macht. Sollte für Dich doch kein Problem sein, denn wenn man 
Deinen, von mir zitierten, Post weiter liest, wird einem doch sehr 
schnell klar, daß Du schon lange erkannt hast wo es krankt. Die 
RTOS-Entwickler sind Dir bestimmt dankbar, wenn Du ihnen auf Sprünge 
hilfst.


MCUA schrieb:
> sogenannte Codeanalysatoren sollten kein Problem damit haben
Werden sie aber haben, da sie unter den gleichen Dogmen geschrieben 
wurden wie sie hier diskutiert werden

Zeno

von Daniel A. (daniel-a)


Lesenswert?

Falk B. schrieb:
...
>     for (i = 0; i < NUM_TCP_PCB_LISTS; i++) {
>       for(pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) {
>         if (pcb->local_port == port) break;
>       }
...
>
> Das war jetzt echt schwer ohne goto . . .

Na offenbar schon, im goto fall wird dort wieder nach oben gesprungen, 
du verlässt statdessen die Schleife. Ein continue wäre hier angesagt, 
oder besser ein goto ;)

von M. K. (sylaina)


Lesenswert?

Zeno schrieb:
> JAEIN! Erst mal sind sie in der Sprache begründet, weil diese zu läßt,
> das man über Arraygrenzen hinaus schreiben kann. Und erst dann kommt der
> Programmierer, der auch nur ein Mensch ist und wie wir alle halt mal
> Fehler macht. Einfaches Beispiel Stringverarbeitung, eine Sache die C
> nicht wirklich kann. Du deklarierst ein Zeichenarray mit 10 Zeichen
> Länge und dann schreibst Du irgendwann mal einen String rein der 11
> Zeichen lang ist und schon ist es passiert. Eigentlich darfst Du ja nur
> 9 Zeichen reinschreiben, weil das letzte Zeichen das berühmte 0 Byte
> ist, auch so eine  Krücke, damit C das Stringende erkennt. Schreibst Du
> 10 Zeichen rein passiert erst mal nichts aber Du merkst es wenn Du den
> String wieder auslesen möchtest. Nicht nur das es keine Strings in C
> gibt, eben nur diese Zeichenarrays, kann C zu allem Überfluss noch nicht
> mal richtig mit Arrays umgehen und Du mußt ihm sagen wie lang Dein Array
> ist. Das sind Basics. Selbst so alte Programmiersprachen wie FORTRAN
> können das.

Naja, du hast damit zum großen Teil sicherlich recht. Man muss aber auch 
sagen: Der Programmierer weiß ja um diese Schwäche, es obliegt also ihm 
sich um das Speicher-Management zu kümmern. Beispeil Strings: Ich weiß, 
dass ich in ein Array schreibe und ich weiß, dass das 0-Byte am Ende 
stehen muss. Ich kann doch also vorher schaun ob der String, den ich in 
ein Array schreiben will, auch da rein passt. Man muss sich halt drum 
kümmern oder man vertraut darauf, dass der String nie länger sein wird 
als das Zielarray wo er rein soll.
Alternativ wird man von niemanden daran gehindert sich Funktionen zu 
überlegen die einem das Leben mit dem Speichermanagement erleichtern. 
Möglicherweise gibt es auch schon welche die man nutzen kann.

von Falk B. (falk)


Lesenswert?

@ Zeno (Gast)

>> Jain. Auch in diesem Beispiel ist goto reine Faulheit oder Schlamperei.
>> Man gewinnt weder Performance noch Lesbarkeit ...
>Ohne Dir jetzt zu nahe treten zu wollen, aber der zitierte Satz spricht
>schon für eine gewisse Arroganz bzw. Ignoranz.

Ein hohes Niveau sieht nur von unten wie Arroganz aus ;-)

>> Auch dort gab es schon üble Fehler. Einer der bekanntesten
>Es gibt keine fehlerfreie Software! Da kannst Du noch so viele
>Codeanalyzer einsetzen wie Du möchtest, denn auch die sind nur von
>Menschen gemacht.

Schwarz-Weiß Denken. Es geht nicht um perfekte, fehlerfreie Software, 
sondern um um die Vermeidung bekannter Fehlerquellen und Konzepte!

von Falk B. (falk)


Lesenswert?

@Daniel Abrecht (daniel-a)

>>     for (i = 0; i < NUM_TCP_PCB_LISTS; i++) {
>>       for(pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) {
>>         if (pcb->local_port == port) break;
>>       }

>Na offenbar schon, im goto fall wird dort wieder nach oben gesprungen,
>du verlässt statdessen die Schleife. Ein continue wäre hier angesagt,
>oder besser ein goto ;)

Über diese Aussage solltest du noch einmal nachdenken . . .

von Mark B. (markbrandis)


Lesenswert?

Zeno schrieb:
> Du darfst Dir gern den kompletten Quelltext ansehen

Klar, weil das ja auch sinnvoll ist. NICHT.

> - die Quellen hatte
> ich ja genannt - und es dann besser machen. Vielleicht solltest Du aber
> auch mit RTOS-Entwicklern in Kontakt treten und ihnen zeigen, wie man es
> richtig macht.

Deine Argumentation ist eine einzige "logical fallacy". Nur weil Code 
mit goto sich in einem Projekt wie RTOS befindet, kann man daraus nicht 
schließen dass die Verwendung von goto gut und richtig und sinnvoll ist.

Wer Ahnung von Softwareentwicklung hat, der weiß dass auch Code von 
schlechter Qualität funktionieren kann. Er kann sogar gut funktionieren, 
in dem Sinne dass er die Anforderungen vollständig erfüllt. Er kann aber 
unnötig schlecht zu lesen, zu warten, zu erweitern sein.

"Code erfüllt Anforderungen" und "Code ist von einer guten Qualität" 
sind mithin also zwei vollkommen verschiedene Dinge.

Ich weiß nicht nach welchen Programmierrichtlinien RTOS entwickelt wird. 
Oder nach welchen Maßstäben die ihre Qualität prüfen. Tun sie das? Ich 
hoffe doch. Aber wir wissen alle, wieviel Budget im durchschnittlichen 
Software-Projekt für die Qualitätssicherung ausgegeben wird - das kann 
auch schon mal gerne gegen Null gehen.

Ich habe in meinem Programmiererleben Hunderttausende Zeilen von Code 
gesehen, und vieles davon war ziemliche Grütze die man so nicht nochmal 
schreiben würde wenn man es neu machen würde. Die Qualität von Code ist 
in vielen Projekten nahezu beliebig. Also auch beliebig schlecht.

Wer goto verteidigt, der hat wahrscheinlich nie in seinem Leben ein 
gutes Buch zum Thema Software-Design gelesen und verstanden. Und der 
schreibt wahrscheinlich auch Funktionen, die oft und gerne über mehrere 
Bildschirmseiten hinweg gehen - und denkt sich nichts dabei.

Es ist niemandem verboten, mal ein gutes Buch zum Thema Software-Design 
zu studieren. Aber nein, das wäre ja zu anstrengend, und man müsste 
vielleicht seine Gewohnheiten beim Programmieren ändern. Das darf 
natürlich nicht sein. Man könnte am Ende noch ein richtig guter 
Entwickler werden. Gott bewahre!

Wer Ironie findet, darf sie behalten. ;-)

: Bearbeitet durch User
von Daniel A. (daniel-a)


Lesenswert?

Falk B. schrieb:
> Ein continue wäre hier angesagt,
>>oder besser ein goto ;)
>
> Über diese Aussage solltest du noch einmal nachdenken . . .

Ups, bei verschachtelten schleifen und break/continue übersehe ich immer 
ein paar schleifen... Schade, dass es in c nicht wie in JavaScript und 
Java labeled blocks gibt.

von nichtCler (Gast)


Lesenswert?

Zeno schrieb:
> nichtCler schrieb:
>> Wer "downgeloaded" schreibt, bei dem gehört auch "goto" zum
>> Sparchumfang.
> Stimmt! Bei Dir gehört es definitiv nicht zum "Sparchumfang" - Du kannst
> noch nicht einmal richtig deutsch. Wer im Glashaus sitzt sollte lieber
> nicht mit Steinen werfen.

Ja, das ist wirklich peinlich für mich, sehe meinen Tippfehler ein und 
würde ihn gerne ungeschehen machen. Aber was ist nur mit dem 
"downgeloaded"? War das ein Tippfehler, ein Rechtschreibfehler oder ist 
das ein noch zu verpönender neuer Wotschöpfungversuch?

von Zeno (Gast)


Lesenswert?

M. K. schrieb:
> Der Programmierer weiß ja um diese Schwäche

Ja und genau das ist der Knackpunkt, es ist vom Programmierer abhängig 
und nicht von der Sprache/Compiler und der macht nun mal Fehler.

von Zeno (Gast)


Lesenswert?

Falk B. schrieb:
> Ein hohes Niveau sieht nur von unten wie Arroganz aus ;-)

Wußte nicht das Arroganz noch steigerungsfähig ist.

von Zeno (Gast)


Lesenswert?

Mark B. schrieb:
> Deine Argumentation ist eine einzige "logical fallacy". Nur weil Code
> mit goto sich in einem Projekt wie RTOS befindet, kann man daraus nicht
> schließen dass die Verwendung von goto gut und richtig und sinnvoll ist.

Schlimm jetzt haben wir schon den 2. Fall wo Programmierer bei einem 
umfänglichen Projekt schwerwiegende Fehler machen.

So langsam kristallisiert sich hier heraus, das nur 2 (eingewisser M.B. 
und F.B) gibt die alles korrekt machen. Ich kann's nur noch mal 
wiederholen: Wie überheblich.

von Zeno (Gast)


Lesenswert?

nichtCler schrieb:
> War das ein Tippfehler, ein Rechtschreibfehler oder ist
> das ein noch zu verpönender neuer Wotschöpfungversuch?

Naja ist wohl eher ein "Wotschöpfungsversuch" im derzeit allgemein 
üblichen Denglisch. Hätte vielleicht eher "heruntergeladen" schreiben 
sollen.
Aber sei weiter vorsichtig mit Steine werfen, denn das Echo könnte 
furchtbar sein.

Zeno

von Zeno (Gast)


Lesenswert?

@nichtCler
Bevor Du wieder meckerst, ja ich habe einen Fehler gemacht und ein 
Leerzeichen vergessen.
Zeno schrieb:
> eingewisser

Korrektur: ein gewisser

von M. K. (sylaina)


Lesenswert?

Zeno schrieb:
> Ja und genau das ist der Knackpunkt, es ist vom Programmierer abhängig
> und nicht von der Sprache/Compiler und der macht nun mal Fehler.

Sag ich ja: Der Programmierer macht den Fehler, nicht die Sprache. Die 
hilft ihm schlimmsten Falls nur nicht den Fehler erst gar nicht zu 
machen ;)

von Daniel A. (daniel-a)


Lesenswert?

Zeno schrieb:
> So langsam kristallisiert sich hier heraus, das nur 2 (eingewisser M.B.
> und F.B) gibt die alles korrekt machen. Ich kann's nur noch mal
> wiederholen: Wie überheblich.

Moment, jetzt bin ich verwirrt wer für und wer gegen goto ist. Hab ich 
das so noch richtig im Kopf:

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?

von nichtCler (Gast)


Lesenswert?

Zeno schrieb:
> Naja ist wohl eher ein "Wotschöpfungsversuch" im derzeit allgemein
> üblichen Denglisch. Hätte vielleicht eher "heruntergeladen" schreiben
> sollen.

Danke.

> ..., denn das Echo könnte furchtbar sein.

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

von Programmierer (Gast)


Lesenswert?

Mark B. schrieb:
> Wer goto verteidigt, der hat wahrscheinlich nie in seinem Leben ein
> gutes Buch zum Thema Software-Design gelesen und verstanden.

Ich glaube nicht, dass ein Buch lesen reicht. Zuerst muss man erkennen, 
welche Probleme "goto" verursacht. Wenn man nur eigenen Code schreibt 
und liest, womöglich außer C-ähnlichen Sprachen nie etwas anderes 
gelernt hat, entwickelt man kein Gespür für die Problem-Ecken. Man 
bleibt auf einem mental niedrigem Niveau hängen.

Hier wurden im wesentlichen zwei "goto"-Konstrukte vorgestellt, wenn 
auch im Zweiten nichteinmal das Wort "goto" vorkommt:

1
switch (x)
2
{
3
  case A:
4
    if (something)
5
      action();
6
    else
7
      goto label;
8
    break;
9
10
  ...
11
}

1
switch (x)
2
{
3
  case A:
4
    if (something)
5
      break;
6
    return;  
7
8
  ...
9
}


Beide Konstrukte sind schlimm. Keine strukturierte Programmierung 
vorhanden. Im Prinzip ist das "switch" nur unnötiges Beiwerk. Der ganze 
Programmablauf beruht komplett auf verschachtelte Sprünge.

Solche Dinge kann man in Foren den Menschen nicht beibringen. Dazu 
benötigt man geduldige Gespräche in denen man den Programmierer zum 
Nachdenken anregt.

Im Prinzip ist es einfach: Wer "goto" verteidigt und nicht missbilligt, 
muss noch ein paar Sprossen die Leiter der Erkenntnis nach oben 
klettern. So wie sich jedes kleine Kind mal die Pfoten an einer heißen 
Herdplatte verbrennen muss, um zu erkennen, dass ein "Achtung, 
gefährlich" der Eltern ernst zu nehmen ist, müssen Programmierer mit 
Goto-Konstrukte sich erst eine blutige Nase holen, z.B. weil man im 
Flieger zum Kunde sitzt, weil ein dummer, vermeidbarer Software-Fehler 
in einer Zeile ein System stillsetzt. So spätestens beim zweiten mal 
sollte man es kapiert haben.

von Programmierer (Gast)


Lesenswert?

Zeno schrieb:
> Ja und genau das ist der Knackpunkt, es ist vom Programmierer abhängig
> und nicht von der Sprache/Compiler und der macht nun mal Fehler.

Nein, das ist zu einfach.

Ein Stecker für eine DC-Gleichspannung ist in verpolungssicherer 
Ausführung deutlich besser, als einer auf dem die Polung nur aufgedruckt 
ist und dennoch falsch zusammengesteckt werden kann.

So ist es auch mit "C" und seinem "goto". Das ist ein Stecker der nicht 
Verpolungssicher ist. Es lohnt sich, den nicht einzusetzen.

von M. K. (sylaina)


Lesenswert?

Programmierer schrieb:
> Nein, das ist zu einfach.

Warum soll das zu einfach sein?

Programmierer schrieb:
> Ein Stecker für eine DC-Gleichspannung ist in verpolungssicherer
> Ausführung deutlich besser, als einer auf dem die Polung nur aufgedruckt
> ist und dennoch falsch zusammengesteckt werden kann.

Na sicher ist es besser, wenn man den Spass so baut, dass Fehler nicht 
möglich sind, keine Frage. Aber, um hier zum Thema zurück zu kommen: Man 
kann auch while-Schleifen und Co prima falsch zusammenstricken und sich 
wundern warum das Programm nicht funktioniert. Und in Fortran und Co 
geht das auch prima da Endlosschleifen zu generieren.

von Falk B. (falk)


Lesenswert?

@ Programmierer (Gast)

>So ist es auch mit "C" und seinem "goto". Das ist ein Stecker der nicht
>Verpolungssicher ist. Es lohnt sich, den nicht einzusetzen.

Ein sehr schönes Beispiel! Das ist Karl Heinz Buchegger würdig!

von rhf (Gast)


Lesenswert?

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.

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.

rhf

von M. K. (sylaina)


Lesenswert?

Falk B. schrieb:
> @ Programmierer (Gast)
>
>>So ist es auch mit "C" und seinem "goto". Das ist ein Stecker der nicht
>>Verpolungssicher ist. Es lohnt sich, den nicht einzusetzen.
>
> Ein sehr schönes Beispiel! Das ist Karl Heinz Buchegger würdig!

Naja, wenn ich schreibe
1
while(myVar < 10) {
2
  myVar = 1;
3
}

ums mal ganz einfach zu halten bin ich da auch nicht wirklich 
"verpolungssicher". Und das gilt auch für andere Schleifen und Co. 
Durchs Knie ins Auge schießen kann man in C nicht nur mit goto, das geht 
mit allen Schleifen prima.

von sepp (Gast)


Lesenswert?

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

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.

von MCUA (Gast)


Lesenswert?

>Der ganze Programmablauf beruht komplett auf verschachtelte Sprünge.
Es gibt keine verschachtelte Sprünge.

von Mark B. (markbrandis)


Lesenswert?

sepp schrieb:
> 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.

Ich gebe einen Kasten Bier aus, sobald es jemandem gelingt diese 
Behauptung zu beweisen.

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

: Bearbeitet durch User
von blablablubb (Gast)


Lesenswert?

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.

Diese Aussage ist reines Blabla.

Goto wird erfolgreich in gut strukturiertem Code angewendet. Dazu gibt 
es genug Beispiel, auch wenn du sie mit dieser Pauschalaussage abweist.
Punkt.

von Mark B. (markbrandis)


Lesenswert?

blablablubb schrieb:
> Goto wird erfolgreich in gut strukturiertem Code angewendet.

Das ist eine Aussage. Aussagen können wahr oder falsch sein. Oder auch 
teilweise wahr. Eine Aussage zu tätigen macht sie alleine noch nicht 
wahr.

> Dazu gibt es genug Beispiel, auch wenn du sie mit dieser Pauschalaussage
> abweist.

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.

Die bisher gezeigten Beispiele kann man alle einem Refactoring 
unterziehen, die den Code besser machen. Den gleichen Code in mehrere 
kleinere Funktionen aufzuteilen macht ihn besser verständlich, und er 
vereinfacht ebenso die Unit Tests. Letztere machen viele Programmierer 
gar nicht erst - ich weiß. Damit geben sie aber von vornherein zu 
Protokoll, dass sie es mit der Softwarequalität eh nicht so genau 
nehmen. Und solchen Leute soll ich vertrauen, wenn sie sagen dass goto 
gut sei?

: Bearbeitet durch User
von MCUA (Gast)


Lesenswert?

>Ich gebe einen Kasten Bier aus, sobald es jemandem gelingt diese
>Behauptung zu beweisen.

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!

von Mark B. (markbrandis)


Lesenswert?

MCUA schrieb:
> 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: 
Eine Funktion, die mehrere Dinge tut anstatt nur eines.

: Bearbeitet durch User
von Mikro 7. (mikro77)


Lesenswert?

Der Thread wird lang und länger...

Hier mal Wikipedia als interessante Quelle (hatten wir noch nicht,
oder?): https://en.wikipedia.org/wiki/Goto#Common_usage_pa...

In den Referenzen findet man dann auch u.a. Linus' Statement dazu:

I think goto's are fine, and they are often more readable than large
amounts of indentation. That's especially true if the code flow isn't
actually naturally indented (in this case it is, so I don't think using
goto is in any way clearer than not, but in general goto's can be
quite good for readability).

Und dann weiter, in seiner gewohnt netten Art: ;-)

Of course, in stupid languages like Pascal, where labels cannot be
descriptive, goto's can be bad. But that's not the fault of the goto,
that's the braindamage of the language designer.

von Mark B. (markbrandis)


Lesenswert?

Mikro 7. schrieb:
> In den Referenzen findet man dann auch u.a. Linus' Statement dazu

Linus Torvalds hat nie ein Buch über Software-Design geschrieben. Oder 
über Software-Architektur. Oder darüber, wie man Software richtig 
testet. Oder darüber, wie man Software so entwickelt dass man eine 
bestimmte Qualität sicherstellen kann.

Warum wohl? ;-)

von Walter S. (avatar)


Lesenswert?

Falk B. schrieb:
> do {
>     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++) {
>       for(pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) {
>         if (pcb->local_port == port) break;
>       }
>       if (pcb->local_port == port) break;
>     }
>   } while (pcb->local_port == port);
>
>   return port;
> }

obwohl ich in den letzten Jahren nur in einem Fall, dafür gleich 
mehrmals goto verwendet habe, nämlich als ich ein Fortranprogramm 1:1 in 
C umgeschrieben habe weil ich die ganzen verschachtelten gotos nicht 
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. Richtig wäre stattdessen
if ( pcb!=NULL )
entsprechend beim while
i < NUM_TCP_PCB_LISTS

: Bearbeitet durch User
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.