TIA V15: In SCL GOTO-Befehl verwenden?

Automatinator

Level-1
Beiträge
115
Reaktionspunkte
2
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen

Ein Teamkollege von mir verwendete GOTO-Befehle in SCL in einer CASE-"Zustandsmaschine" um gewisse Befehle/Abläufe "Zeitkürzer" im OB1 (Zyklischer OB) abzuwickeln. Auch desshalb weil in den einzelnen CASE-Schritten Sub-CASE-Zustände programmiert wurden. Und da für jeden CASE-Zustandswechsel ein Zyklus benötigt wird, verwendete er GOTO's.

Als Beispiel: Wenn der OB1 Zykluszeit 15ms betrug, wurde je nachdem ein Befehl erst nach Bsp.weise 6x15ms=90ms Abgearbeitet.
Und mit Verwendung von der GOTO's in 15ms (+ etwas mehr durch die GOTO-Sprünge).


Mir wurde immer gesagt von den Sprungfunktionen sollte man immer die Finger lassen... auch Wikipedia ist der Meinung:

Zitat Wikipedia zum Thema Strukturierte Programmierung:
Die bekannteste Konsequenz dieses Prinzips ist die Vermeidung oder – abhängig von der Programmiersprache – der eingeschränkte und standardisierte Einsatz der Sprunganweisung, des GOTO. Das Ergebnis der häufigen Verwendung dieser Anweisungen wird häufig abfällig als Spaghetticode bezeichnet.


Kann mir einer von euch sagen wieso man auch hier die GOTO's Meiden sollte? Gibt es hier nachteile beim Software-Warten oder Debuggen? (Debuggin in V15 möglich).

Danke im Vorraus!

Gruss
 
Hallo zusammen

Ein Teamkollege von mir verwendete GOTO-Befehle in SCL in einer CASE-"Zustandsmaschine" um gewisse Befehle/Abläufe "Zeitkürzer" im OB1 (Zyklischer OB) abzuwickeln. Auch desshalb weil in den einzelnen CASE-Schritten Sub-CASE-Zustände programmiert wurden. Und da für jeden CASE-Zustandswechsel ein Zyklus benötigt wird, verwendete er GOTO's.

Als Beispiel: Wenn der OB1 Zykluszeit 15ms betrug, wurde je nachdem ein Befehl erst nach Bsp.weise 6x15ms=90ms Abgearbeitet.
Und mit Verwendung von der GOTO's in 15ms (+ etwas mehr durch die GOTO-Sprünge).


Mir wurde immer gesagt von den Sprungfunktionen sollte man immer die Finger lassen... auch Wikipedia ist der Meinung:

Zitat Wikipedia zum Thema Strukturierte Programmierung:



Kann mir einer von euch sagen wieso man auch hier die GOTO's Meiden sollte? Gibt es hier nachteile beim Software-Warten oder Debuggen? (Debuggin in V15 möglich).

Danke im Vorraus!

Gruss
Egal, wo man programmieren lernt:
Eines der ersten Dinge die man lernt lautet
Hände weg vom GOTO
und wenn es keine Möglichkeit gibt, das ähnlich elegant zu lösen, dann gilt die Regel:
Hände weg vom GOTO

Wenn sich die Laufzeitoptimierung beim CASE nur durch GOTO-Befehle erkaufen lässt, sollte man sich die Frage stellen, ob CASE die geeignete Lösung für die Zustandsmaschine ist, oder ob nicht die Verwendung einer einfachen IF-Liste die bessere Lösung ist.

lg
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Einfach weil es von der Lesbarkeit/Wartbarkeit nicht schön ist die Funktion kann durch GOTO natürlich durchaus evektiver werden. Z.B. eine Case-Anweisung braucht für jeden Case einen Zyklus mit GOTO könnte man mehrere Cases in einem Zyklus machen aber ist das Notwendig?

Sonnst das was Max sagt.
 
Zuletzt bearbeitet:
Einfach weil es von der Lesbarkeit/Wartbarkeit nicht schön ist die Funktion kann durch GOTO natürlich durchaus evektiver werden. Z.B. eine Case-Anweisung braucht für jeden Case einen Zyklus mit GOTO könnte man mehrere Cases in einem Zyklus machen aber ist das Notwendig?
Deine Antwort stand eigentlich schon in der Fragestellung drinnen......
 
Kann mir einer von euch sagen wieso man auch hier die GOTO's meiden sollte?
Weil die "HochsprachenProgrammierer" damit nicht klar kommen. Andererseits, ich glaube mich richtig zu erinnern, in Fortran IV waren doch bei jeder If-Abfrage 3 Sprungziele anzugeben - eins für kleiner, eins für gleich und eins für grösser. Und da gab es sogar einen Befehl namens "Continue", mit dem man dem Compiler helfen musste, den "roten Faden" wieder zu finden.
In jeder ProgrammierSprache kann man unübersichtlichen Code produzieren. Das gilt für Sprachen, die zur Bildung von Selektionen und Iterationen nichts anderes zu bieten haben, als "Goto" bzw. "Then", direkt gefolgt von der SprungZielAngabe. Das gilt genauso für Sprachen, die absolut kein "Goto" kennen - damit hatte ich mal in einer Cobol-Version zu kämpfen, in der nur knappe 48KB für's Programm zur Verfügung standen - wie sehr habe ich mich damals nach einer Möglichkeit gesehnt, SpaghettiCode produzieren zu können.
Fazit: man kann Goto nicht grundsätzlich verdammen, aber es ermöglicht bzw. verleitet dazu, SpaghettiCode zu produzieren.
Den von Dir aufgezeigten Zusammenhang zwischen Case und Zyklus kann ich nicht wirklich nachvollziehen. Wenn es tatsächlich so sein sollte, dann könnte man evtl. ein Case-Konglomerat in mehrere aufteilen, um "FortSchritte" etwas zügiger zu erreichen? Aber wahrscheinlich geht es um SchrittKetten, von denen man gar nicht will, dass sie schneller "durchrauschen", als man gucken kann?
Ich würde versuchen, das Problem mit Case (ohne Goto) zu lösen, aber vorher zu klären, was denn wirklich zum DurchNudeln der EhrenZyklen führt. Ich werde das Gefühl nicht los, dass das bisherige Konzept irgendwie nicht zu den Anforderungen passt.
Gruss, Heinileini
PS: Case kann man doch auch durch if gefolgt von (vielen) ElseIf ersetzen ... aber der eigentliche Haken dürfte ohnehin woanders zu suchen sein.
 
sofortige Schrittweiterschaltung ohne GOTO

Wenn es nur um die sofortige Schrittweiterschaltung geht - das läßt sich prima übersichtlich ohne GOTO programmieren:
Code:
[COLOR="#0000FF"]REPEAT[/COLOR] [COLOR="#008000"]//eine Schleife für den Rückwärtssprung zur sofortigen Schrittweiterschaltung[/COLOR]

  CASE Schrittnummer OF
    1: TuWas1();
       Schrittnummer := 2; [COLOR="#008000"]//mit Schrittnummer 2 im nächsten Zyklus fortsetzen[/COLOR]
                           [COLOR="#008000"]//springe hinter END_CASE und finde da das EXIT aus der REPEAT-Schleife[/COLOR]

    2: TuWas2();
       Schrittnummer := 3; [COLOR="#008000"]//mit Schrittnummer 3 fortsetzen sofort[/COLOR]
       [COLOR="#0000FF"]CONTINUE[/COLOR];           [COLOR="#008000"]//springe zu UNTIL und wiederhole ab REPEAT (weil 0=1 niemals erfüllt)[/COLOR]

    3: ...

  END_CASE;

  [COLOR="#0000FF"]EXIT[/COLOR]; [COLOR="#008000"]//CASEs ohne das CONTINUE verlassen die REPEAT-Schleife (Sprung zu "//weiter" hinter UNTIL)[/COLOR]

[COLOR="#0000FF"]UNTIL 0=1 END_REPEAT[/COLOR];      [COLOR="#008000"]//Rückwärtssprung (zurück zu REPEAT) weil 0=1 niemals erfüllt[/COLOR]

[COLOR="#008000"]//weiter...[/COLOR]

Harald
 
Ich sehe nichts schlechtes, wenn bei einer Sprungleiste zu verschiedenen Marken / Programmteilen gesprungen wird. Deshalb wurde ja SCL erfunden :ROFLMAO:
Wo ist das Problem?
Wenn die Abarbeitung des OB1 verzögert wird, na und? Der macht doch alles zyklisch bzw richtig, wenn er richtig programmiert wurde.
Wenn es zeitkritisch ist ein festes Zeitraster gebraucht wird, dann eben in die entsprechenden AlarmOBs damit.

bike
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn es nur um die sofortige Schrittweiterschaltung geht - das läßt sich prima übersichtlich ohne GOTO programmieren..

Harald, das ist kein Spagetticode, das ist eingedickte Buchstabensuppe.
Nieder mit GOTO, hoch lebe CONTINUE und EXIT :ROFLMAO: !
 
Zuletzt bearbeitet:
... das läßt sich prima übersichtlich ohne GOTO programmieren: ...
"Prima übersichtlich" aber auch nur, weil Du's so schön farbig hervorgehoben und unnötiges Beiwerk weggelassen hast und weil es im Zusammenhang dieses Thread auftaucht.
Würde man völlig unvorbereitet so etwas in einem Programm lesen ... na, ich möchte nicht wissen, wie viel Kopfzerbrechen dieses Konstrukt so manchem mehr oder weniger aufmerksamen Leser bereiten würde. Das ist doch ganz schön um mehrere Ecken (SpaghettiKnoten) gedacht!
Und dennoch: chapeau! Endlich eine Anwendung des Continue-Befehls, die erahnen lässt, wie er zu seinem Namen gekommen sein könnte.

Mir ist immer noch unklar, wieso die ZustandsMaschine durch Einsparung eines Zyklus zur ZustandsZeitmaschine wird, die eine nennenswerte Anzahl (im Beispiel 6) Zyklen einsparen kann.
Anscheinend benötige ich ein paar Zyklen mehr, bis bei mir der Groschen fällt.
Gruss, Heinileini

PS:
@bike
... Deshalb wurde ja SCL erfunden ...
War aber nicht nötig - gab's doch in AWL auch schon!
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
:D Wie unterschiedlich die Geschmäcker doch so sind :ROFLMAO:
Manche bevorzugen ..zig GOTO-Sprünge zu womöglich ..zig verschiedenen Sprungzielen und halten das für übersichtlicher als einen Standard-Sprung ("CONTINUE") zu nur einem vom Compiler automatisch vergebenen Sprungziel (ohne Chance sich beim Ziel zu vertippen). Das scheint mir eher eine Form von "Ich will unbedingt Hochsprache programmieren, will aber nur IF..THEN, FOR..TO, CASE und GOTO benutzen, weil die anderen Konstrukte sind mir zu unverständlich und überhaupt unnütz" ;)

Gruß Harald
 
Aber um eine CASE-Anweisung nur weil ich ein GOTO vermeiden will, eine völlig unnütze endlose REPEAT-Schleife bauen? Wo sich jeder fragt, was soll das da denn?

Ich bin ja ein Freund des Durchfallens bei switch/case in C bei fehlender break Anweisung, da gibt es aber auch Leute die das für einen der Nachteile bei C halten.
 
Aber um eine CASE-Anweisung nur weil ich ein GOTO vermeiden will, eine völlig unnütze endlose REPEAT-Schleife bauen?
Es geht nicht nur um ein einziges GOTO sondern um viele, welche vermieden werden können.

Die REPEAT-Schleife ist dafür da,
- damit die CASEs in beliebiger Reihenfolge stehen können
- damit man keine GOTO braucht und keine Sprungmarken für die GOTO verwalten muß - es wird durch den Compiler immer der "Sprungverteiler" (CASE ...) angesprungen
- damit man sich nicht darum kümmern muß, daß die Zuweisung der nächsten Schrittnummer zum GOTO-Sprungziel passt
- damit nicht zusätzlich zur Schrittnummer noch eine Variable verwaltet werden muß, welche den Rücksprung zum "Sprungverteiler" (ja/nein) steuert
- es reicht lediglich, nach der Zuweisung der nächsten Schrittnummer ein CONTINUE zu schreiben (dann wird der nächste Schritt/CASE sofort im selben Zyklus angesprungen), oder kein CONTINUE (oder ein EXIT) zu schreiben (dann wird der nächste Schritt/CASE im nächsten Zyklus angesprungen)
- für alle Schritte, welche nicht sofort zum nächsten Schritt weiterspringen sollen (z.B. weil sie auf etwas warten) ist das eine EXIT vor dem UNTIL da, wodurch effizient die endlos-REPEAT-Schleife verlassen wird (die UNTIL-Bedingungsprüfung übersprungen wird)

Man könnte aus der "unnützen endlos-REPEAT-Schleife" eine Schleife mit kontrollierter/variabler Abbruchbedingung machen, doch das wäre aufwändiger.

Weil hier die Aufgabenstellung ist, im selben Zyklus weitere Schritte auszuführen, finde ich es durchaus berechtigt, für den (wiederholten) Rücksprung zum Sprungverteiler ein REPEAT-Konstrukt zu verwenden. (WHILE könnte man auch nehmen, doch das wird langsamer, weil da immer zuerst die WHILE-Bedingung geprüft wird. FOR könnte man auch nehmen - allerdings nicht bei Siemens-TIA-SCL, weil da der Compiler so doof optimiert)

PS: Mit so einer REPEAT-Schleife kann man übrigens prima CASE-Abschnitte vorzeitig per EXIT verlassen, ohne nicht mehr auszuführende Anweisungen in IF-Zweige packen zu müssen und ohne GOTO zu verwenden.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
"Leere" Repeat oder While Schleifen stehen bei mir auf der gleichen Stufe wie Goto.
Es sind einfach Anweisungen bei denen mein Gehirn einen Alarm-OB startet und ich weiß, dass hier Vorsicht geboten ist.
Beim Beispiel von Harald hätte ich wahrscheinlich zum Goto gegriffen.

Gruß
Blockmove
 
"Leere" Repeat oder While Schleifen stehen bei mir auf der gleichen Stufe wie Goto.
Es sind einfach Anweisungen bei denen mein Gehirn einen Alarm-OB startet und ich weiß, dass hier Vorsicht geboten ist.
Beim Beispiel von Harald hätte ich wahrscheinlich zum Goto gegriffen.
Mein Beispiel ist doch gar keine "leere" REPEAT-Schleife, sondern sie ist genau deshalb drin, weil da tatsächlich ein Programmteil bedingt wiederholt werden soll. Wieso soll man dafür keine REPEAT-Schleife einsetzen dürfen? Mit dem REPEAT hat man wenigstens ein "Achtung!"-Zeichen, daß da ein Rückwärtssprung ist, was man bei mehreren GOTO nicht so deutlich sehen würde.

Das Ungewöhnliche an der Schleife ist doch lediglich, daß die Abbruchbedingung nicht aufwändig über eine Variable realisiert ist sondern über ein einziges "EXIT". Ist sowas für "Hochsprachen-Programmierer" schon zu hoch? ;)

Harald
 
Wenn dann "Gotoismus" ... 8)

Aber mal im Ernst ... dies ist jetzt wieder so ein "Meinungs-Thread" - man kann also diese und nicht diese Meinung dazu haben ...
Ich persönlich hatte bisher erst einen einzigen Anwendungsfall für ein GOTO und das habe ich auch nur deshalb gemacht weil der IF-Bereich über so viele Zeilen ging das die Zuordnung IF-END_IF trotz einem entsprechenden Kommentar am END_IF nicht mehr so schön ersichtlich war (für meine Kollegen - ich wäre auch so klar gekommen).
Die Variante von Harald kannte ich aber gar nicht, würde ich selbst nicht so machen ... aber allein das so zu machen wäre ich nicht drauf gekommen - von daher auf alle Fälle schonmal interessant ...

Gruß
Larry
 
Zurück
Oben