Rolf M. schrieb:> Es gibt ja auch noch den eigentlich viel cooleren umgekehrten Konstrukt> names COMEFROM.
Auch unter dem Namen catch oder except bekannt.
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.
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.
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.
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.
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? :DM. 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
intadd(inta,intb){
2
returna+b;
3
}
Was muss ich hier tun, dass b nicht mehr benutzt wird? Genau, ich muss
die Funktion ändern:
1
intadd(inta,intb){
2
returna;
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)
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".
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?
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.
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. ;-)
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.
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" ;)
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
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.
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?
@ 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
;-)
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.
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
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.
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.
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!
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).
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.)
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.
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*
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 :).
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.
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 :)
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? ;)
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.
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?
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:
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.
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.
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.)
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. ;-)
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.
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 :)
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
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!
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.
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.
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
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
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
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.
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.
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.
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
>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.
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?
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:
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;
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.
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!
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.
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.
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.
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.
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.
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.
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
gotoSchleifenbeginn;
5
}
6
gotoSchleifenende;
7
8
Schleifenbeginn:
9
// Schleifeninhalt
10
gotoSchleifenbedingung;
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.
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.
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.
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.
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!
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.
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...
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.
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.
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:
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.
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!
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.
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.
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.
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.
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.
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.
@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 ;-)
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.
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?
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 :-)
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.
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:
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 ^^)
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.
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:
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
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.
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
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
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.
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.
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.
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 …
Um mal Zenos Punkt zu stützen kann man auch wieder relativieren. Wie
immer im Leben.
1
uint32_ttimeout=tick_ms+100;
2
while(tick_ms<timeout){
3
(...)
4
}
5
6
gegen
7
#define TIMEOUT_MS 100
8
9
uint32_ttimeout=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.
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
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.
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).
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.
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.
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.
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
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.
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.
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.
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! ;-)
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 ;)
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.
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
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.
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
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...
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.
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."
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.
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?
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 ;)
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
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.
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.
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
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
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
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.
@ 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ß!
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.
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.
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.
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.
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. ;)
>> 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
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.
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++.
> 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.
@ 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 ;-)
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
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 SparteHerbert 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:
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
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
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.
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.
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.
@ 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.htmlhttps://en.wikipedia.org/wiki/Therac-25
Falk B. schrieb:> Das war jetzt echt schwer ohne goto . . .
Ehrlich gesagt finde ich die Variante mit goto in dem Fall etwas
übersichtlicher (!= besser).
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
caseGET_DESCRIPTOR:
2
if(bmRequestType==0x80)usb_get_descriptor();
3
elsegotounsupported_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
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.
@ 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.
> 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)
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
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 ;)
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.
@ 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!
@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 . . .
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. ;-)
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.
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?
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.
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.
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
@nichtCler
Bevor Du wieder meckerst, ja ich habe einen Fehler gemacht und ein
Leerzeichen vergessen.
Zeno schrieb:> eingewisser
Korrektur: ein gewisser
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 ;)
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?
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.
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
caseA:
4
if(something)
5
action();
6
else
7
gotolabel;
8
break;
9
10
...
11
}
1
switch(x)
2
{
3
caseA:
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.
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.
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.
@ 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!
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
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.
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.
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.
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.
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?
>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!
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.
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.
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? ;-)
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