Gelöst: TC3: Auswertung der Bedingung bei IF-Abfrage nach erster nicht erfüllter abbrechen

Beiträge
6.842
Reaktionspunkte
1.670
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
vermutlich habe ich das ganz woanders (z.B. C++) gesehen.
Normalerweise werden bei einer IF-Abfrage ja immer alle Bedingungen ausgewertet. Ich meine aber mal gesehen zu haben, dass man (wie auch immer) es erreichen kann, dass ab der ersten nicht erfüllten Bedingung die weitere Auswertung abgebrochen wird.
Weiß einer, ob das in TC3 geht?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Mit AND_THEN und OR_ELSE aber nur in ST
In FUP geht es auch, wenn man ein komplettes ST-Statement an den Bausteineingang schreibt.
Du bist mein Held, genau das war es. Ich habe mir bei Google echt einen Wolf gesucht und nichts gefunden.
Mal OT, arbeitest Du bei Beckhoff, weil Du teilweise echt extrem gutes Hintergrundwissen hast.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Mal OT, arbeitest Du bei Beckhoff, weil Du teilweise echt extrem gutes Hintergrundwissen hast.
Mensch Oliver, Du muss Dich aber auch nicht verstecken. Danke für Deine Einschätzung, ich fühle mich schon fast geadelt... :LOL:

Ich bin bei der Konkurrenz groß geworden, war mal Siemensianer.

Nein bei Beckhoff war ich nicht, habe aber teilweise ganz schön nah mit denen zusammengearbeitet. Und in den 20 Jahren, wo ich schon mit TwinCAT arbeite, kommt einiges an Erfahrung zusammen. Siemens-Steuerungen habe ich vor 5 Jahren endgültig den Rücken gekehrt und mache das nur noch im Ausnahmefall.

Ich bin also ein echter TwinCAT-Fan.
😎
 
Die zwei Operatoren wurden, soweit ich weiß, irgendwann mal in die IEC 61131-3 aufgenommen. Gibt's auch bei Codesys.
Den "AND_THEN" find ich ja noch ganz nachvollziehbar.
"OR_ELSE" naja ...

Hier mal das Beispiel aus der Codesys Hilfe:
Code:
VAR
        bEver: BOOL;
        bX: BOOL;
        dw: DWORD := 16#000000FF;
END_VAR

bEver := FALSE;
bX := dw.8 OR_ELSE dw.1 OR_ELSE (bEver := TRUE);

Vorallem hier nicht in ner IF-Abfrage sondern in ner Zuweisung.

Oli die zwei Operanten kannst du dann in "SPS für Fortgeschrittene" packen
:)
 
Ich war jetzt etwas irritiert von der Fragestellung. Mit IF hat AND_THEN, OR_ELSE nichts direkt zu tun, sondern ist nur eine Lazy Auswertung von boolschen ausdrücken ähnlich wie bei Python.

Q := A AND_THEN B; // Ist A := FALSE, wird B nicht mehr ausgewertet.

Man könnte es höchstens Analog so programmieren und hätte dann den Bezug wieder zum IF-ELSE

IF A THEN
IF B THEN
Q := TRUE;
EN_ID;
ELSE
Q := FALSE;
END_IF;

Die Lazy-Auswertung hat den Vorteil, dass es eine kürzere Schreibweise ist und man nicht in blöde Fehler läuft wie Zugriff auf Array-Elemente die es nicht gibt oder Null-Division:

Q := i > 0 AND i<= 10 AND_THEN a;
 
Was ist an OR_ELSE denn auszusetzen? :unsure:

Wenn links bereits TRUE ist, muss rechts nicht weiter ausgewertet werden.(y)

Naja auszusetzen ist daran nichts. Aber vielleicht nicht gleich selbsterklärend.
Daher finde ich auch das Besipiel aus der Codess-Hilfe dazu nicht schlecht.
Da wird sich mancher Anfänger fragen was der Unterschied zwischen

Code:
bX := dw.8 OR dw.1 OR (bEver := TRUE);
und
Code:
bX := dw.8 OR_ELSE dw.1 OR_ELSE (bEver := TRUE);
ist
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Frage: Steht das so in der Hilfe?
bX := dw.8 OR dw.1 OR (bEver := TRUE);und
bX := dw.8 OR_ELSE dw.1 OR_ELSE (bEver := TRUE);
Weil, das wird sich so nicht übersetzen lassen - oder? :unsure:
(bEver := TRUE) ist eine Zuweisung und kein Vergleich - und als Vergleich (bEver = TRUE) wäre der auch halb sinnlos. Liege ich hier falsch? :oops:

Edit: Ich habe mir das Beispiel mal in der Codesys-Hilfe angeschaut - und denke gerade die ganze Zeit: "Häää.. Wie bitte? ... Muss ich das verstehen?"
 
Zuletzt bearbeitet:
Frage: Steht das so in der Hilfe?

Weil, das wird sich so nicht übersetzen lassen - oder? :unsure:
(bEver := TRUE) ist eine Zuweisung und kein Vergleich - und als Vergleich (bEver = TRUE) wäre der auch halb sinnlos. Liege ich hier falsch? :oops:

Edit: Ich habe mir das Beispiel mal in der Codesys-Hilfe angeschaut - und denke gerade die ganze Zeit: "Häää.. Wie bitte? ... Muss ich das verstehen?"

Deshalb fand ich ja das Hilfebeispiel https://content.helpme-codesys.com/de/CODESYS Development System/_cds_operator_or_else.html so nett. Verschiedene Datentypen und auch noch die "versteckte" Zuweisung und das in einer "simplen" boolschen Verknüpfung.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
(bEver := TRUE) ist eine Zuweisung und kein Vergleich
... und liefert das Ergebnis der Zuweisung als Wert an die Weiterverknüpfung (wie in C)
"KI" schreibt:
Das Ergebnis einer Zuweisung in C ist der Wert, der der linken Seite zugewiesen wird. Das bedeutet, nach einer Operation wie a = b, hat der gesamte Ausdruck a = b den Wert von a (nachdem die Zuweisung durchgeführt wurde).

Das verwirrende dieses "sehr konstruierten" Anwendungsbeispiels zu OR_ELSE
Code:
bEver := FALSE;
bX := dw.8 OR_ELSE dw.1 OR_ELSE (bEver := TRUE);
ist, dass es da gar nicht um die Zuweisung an bX geht, sondern um die Zuweisung an bEver ! bX bekommt auf jeden Fall TRUE zugewiesen, bEver wird nur dann TRUE, wenn dw.8 und dw.1 beide FALSE sind. Alles klar? :cool:

Die 2 Zeilen machen folgendes:
Code:
bEver := FALSE;
IF NOT dw.8 THEN
  IF NOT dw.1 THEN
    bEver := TRUE;
  END_IF;
END_IF;
bX := TRUE;

Man könnte auch programmieren:
Code:
bEver := NOT dw.8 AND NOT dw.1;
bX := TRUE;
Aber das wäre zu einfach, das würde ja jeder sofort verstehen ;)

Ziel von OR_ELSE ist, die Verknüpfung schon vorzeitig abzubrechen, wenn klar ist, dass das Ergebnis auf jeden Fall TRUE sein wird (AND_THEN : wenn das Ergebnis FALSE sein wird). Sinnvoll nutzbar ist das z.B., wenn man "lazy" in nur einer Codezeile einen Operand (z.B. Pointer) erst prüfen will, und nur weiterrechnet, wenn der Operand im geprüften Bereich ist. (Oder wenn man im "Normalfall" ein paar Nanosekunden Rechenzeit sparen will.) Das Codesys-Beispiel zu AND_THEN ist da sinnvoller und verständlicher und spart 2 Zeilen Quellcode (mit IF und END_IF):
Code:
IF (ptr <> 0 AND_THEN ptr^ = 99) THEN...
 
Zurück
Oben